{"thread":{"id":"60526","subject":"gitmodulesSymlink .gitmodules is a symbolic link","startedAt":"2023-11-15T16:01:49Z","lastAt":"2023-11-16T20:27:19Z","messageCount":2,"participants":["flobee.code","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"484939","messageId":"CAM30mqasEjEBbn1vSUwvKP6LLjAFSw3xoeLrB1zLWnH37Z2fUg@mail.gmail.com","threadId":"60526","inReplyTo":null,"subject":"gitmodulesSymlink .gitmodules is a symbolic link","fromName":"flobee.code","fromEmail":"flobee.code@gmail.com","sentAt":"2023-11-15T16:01:10Z","receivedAt":"2023-11-15T16:01:49Z","isPatch":false,"sender":{"key":"flobee.code@gmail.com","avatar":null},"body":"Hi\n\nI can not rebase symlinks of an 6 years old repository.\nSee attached files (two languages, EN auto translation) for more details.\nCreated with `git bugreport`\n\nKind regards\nFlorian\n\n\n[EN](#EN) Translated by https://www.deepl.com/translator\n\n\n\n# EN\n\nThank you for filling out a Git bug report!\nPlease answer the following questions to help us understand your problem.\nunderstand your problem.\n\n\nWhat did you do before the error occurred? (Steps to reproduce your error\nreproduce your error)\n\n\nFor 6 years I only did remote pushes locally to my local master.\ngithub.com then refused to accept one.\n\n\nThe reason: \nAnd now github.com but also `git` itself are bitching in detail.\n\n\ngithub.com, as it no longer accepts a push:\n    \n    index-pack failed\n    remote: error: object [hash]: gitmodulesSymlink: .gitmodules is a symbolic link\n\n\nAnd `git` itself also aborts. So I can't solve the problems this way.\n\n\n    git filter-branch --tree-filter 'rm -f .gitmodules' HEAD\n    Rewrite [SomeHash] (3/185) (0 seconds passed, remaining 0 predicted) \\\n        error: Invalid path '.gitmodules' Could not initialize the index\n\n\nThe same attempt also failed with an older VM where `git`\nversion 2.11.0 was still available.\n\n\n\n\n\nWhat did you expect to happen? (Expected behavior)\n\nRebase should work. Always :-)\n\n\n\nWhat happened instead? (Actual behavior)\n\nAbort of git.\n\n    git filter-branch --tree-filter 'rm -f .gitmodules' HEAD\n    Rewrite [SomeHash] (3/185) (0 seconds passed, remaining 0 predicted) \\\n        error: Invalid path '.gitmodules' Could not initialize the index\n\n\n\nWhat is the difference between what you expected and what actually happened?\nreally happened?\n\nWith a current git version I can't fix such errors.\n\nBut in general I think the exclusion of symlinks to git system files is a mistake. It is implemented too sweepingly in my eyes.\n\n\nAny other comments you would like to add:\n\n\nMy `.gitmodules` were always a matching file in the same directory to\nto become aware that something is changing during a merge.\nBranches are staging areas for me, among other things) \n```\n    .gitmodules -> symlinks to one of these files \n                    (depending on the current branch)\n\n        -> .gitmodules_stable\n                ^ ------------------ Staging to stable, release\n        -> .gitmodules_testing\n                ^ ------------------ Staging to testing, testing and preview\n        -> .gitmodules_unstable\n                ^ ^ ^---<---------<-- Feature branch A\n                +-----<---------<-- Feature branch B\n                +-------<---------<-- Feature branch C ...\n```\n\nWith a merge unstable -> testing (-ff), settings from unstable would simply be\nwould simply be included/adopted in testing without drawing attention to it.\nattention. This also has the consequence that you are no longer made aware\nthat the dependencies of the submodules must also be raised,\nbefore the merge is clean/finished.\n\nIf you are working on several submodules, this makes perfect sense. Especially\nif you don't have or want to have everything online in order to check/test the current\nto check/test the current status etc. before you then bind the hashes of the submodules and\nthen make everything public piece by piece depending on the dependency.\nWhat an effort :-/\n\nWith `git` itself (version 2.39.0, Debian Bookworm, 2023) you can still work locally.\ncontinue to work. With github.com, however, the fun is over. If it is in the\nrepository `git` system files like `.gitignore` or `.gitmodules` that are symlinks\nare symlinks, github.com refuses to do any work to fix the bugs.\nthe bugs. Neither via the web interface nor via `git push --force` itself. Whew.\n\nSo: After 6 years! In between there were local updates from time to time, but these were\nwere not made public. The operating system, a Debian, is updated about every\nupdated every two years. So there have been at least 3 new `git` versions since then for\nfor this project. With the current version of `git` I cannot fix the problems\nfix the problems. And that is really bad!\n\n## Solution\n\nOption 3. was the solution. A Debian Wheezy (7.3) brought a `git` \nversion 1.7.10.4, which I used to rebase one of the known and problematic commits. \nknown and problematic commits. I may have traveled too far into the\npast, but this gave me a basis for testing.\nMaybe it will stay that way and everything will be fine again?\n\nFollowing this, and in order to do everything automatically again, the\ngit filter-branch came to mind again:\n\n    git filter-branch --tree-filter 'rm -f .gitmodules' HEAD\n\nDid its job, but didn't help anything Direction github.com as `push --force` for\nfor this branch.\n\n    - git filter-branch --tree-filter 'rm -f .gitmodules' HEAD\n    + git filter-branch --tree-filter 'rm -f .gitmodules'\n\nSo: complete and over everything please.\n\nBut to make this situation tidy:\n\n    .gitmodules ->- symlink to one of these... ->-\n    -> .gitmodules_master\n    -> .gitmodules_stable\n    -> .gitmodules_testing\n    -> .gitmodules_unstable\n\n\n'rm -f .gitmodules' deletes, but does not delete the underlying bindings of the \nsubmodules. Here, too, there were mixtures in the use/application, as the\nhistory clearly showed on closer inspection. But the roadmap for doing it this way \nremained consistent.\n\nI had to fetch the local repository from the backup quite often in order to be able to repeat the many test steps.\nto be able to repeat the many steps of tests...\n\nFinally: Submodules (`.gitmodules`) were always a symlink in the idea.\nSo in order for it to fit for the repair in the future, all symlinks must be resolved into a\nreal file, so that the rebase via `git filter-branch\n--tree-filter` can run cleanly and the dependencies in the base remain clean.\nremain clean. And that looks like this:\n\n    # If .gitmodules is a symlink: \n    # - Find the path to the real file\n    # - Delete the symlink\n    # - Copy the real file to .gitmodules\n    git filter-branch --tree-filter \\\n        'if [ -h .gitmodules ];then loc=$(readlink .gitmodules); rm -f .gitmodules; cp $loc .gitmodules; fi;'\n    \nThis solved the problem. Symlinks removed and replaced with the real content\nreplaced by the real content. However, the complete history has now been rewritten. Locally as\nas well as the newer `git` versions (clients and local server) reported\nno more errors.\n\n# Conclusion\n\nI don't like the way `git` currently works. Symlinks help in\nmy case. They are transparent and available in every branch within the repository\nand are maintained. \n\nThe most important thing: they make work easier as they draw attention to changes.\nchanges. This saves an enormous amount of time and running around afterwards if you forget to\nto correct the submodules because with an almost forward merge it is simply treated \ntreated as new = better. Submodules are bound in the same branch workflow\nin the same branch workflow.\n\n\n\n\n\nPlease check the rest of the error report below.\nYou can delete any line you do not want to report.\n\n\n[System Info]\ngit Version:\ngit version 2.39.2\ncpu: x86_64\nno commit associated with this build\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nuname: Linux 6.1.0-13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.55-1 (2023-09-29) x86_64\nCompiler Info: gnuc: 12.2\nlibc Info: glibc: 2.36\n$SHELL (typically, interactive shell): /bin/zsh\n\n\n[Aktivierte Hooks]\n\n\n\n[DE](#DE)\n[EN] See other text file\n\n\n\n# DE\n\nVielen Dank für das Ausfüllen eines Git-Fehlerberichts!\nBitte antworten Sie auf die folgenden Fragen, um uns dabei zu helfen, Ihr\nProblem zu verstehen.\n\nWas haben Sie gemacht, bevor der Fehler auftrat? (Schritte, um Ihr Fehler\nzu reproduzieren)\n\n6 Jahre lang habe ich nur lokal zu meinem lokalen master remote pushes gemacht.\ngithub.com hat dann eine Annahme verweigert.\n\nDer Grund: \nUnd nun sind github.com aber auch `git` selbst im Detail zickig.\n\ngithub.com, da es einen Push nicht mehr akzeptiert:\n    \n    index-pack failed\n    remote: error: object [hash]: gitmodulesSymlink: .gitmodules is a symbolic link\n\nUnd `git` selbst bricht auch ab. Ich kann die Probleme so also nicht lösen.\n\n    git filter-branch --tree-filter 'rm -f .gitmodules' HEAD\n    Rewrite [SomeHash] (3/185) (0 seconds passed, remaining 0 predicted) \\\n        error: Invalid path '.gitmodules' Could not initialize the index\n\nDer gleiche Versuch scheiterte ebenfalls mit einer älteren VM, wo noch `git`\nVersion 2.11.0 verfügbar war.\n\n\n\nWas haben Sie erwartet, was passieren soll? (Erwartetes Verhalten)\n\nRebase soll funktionieren. Immer :-)\n\n\n\nWas ist stattdessen passiert? (Wirkliches Verhalten)\n\nAbbruch von git.\n\n    git filter-branch --tree-filter 'rm -f .gitmodules' HEAD\n    Rewrite [SomeHash] (3/185) (0 seconds passed, remaining 0 predicted) \\\n        error: Invalid path '.gitmodules' Could not initialize the index\n\n\n\nWas ist der Unterschied zwischen dem, was Sie erwartet haben und was\nwirklich passiert ist?\n\nMit einer aktuellen git Version kann ich derartige Fehler nicht bereinigen.\n\nAber ansich halte ich das ausgrenzen von symlinks zu git system Dateien für einen Fehler. Es ist zu Pauschal in meinen Augen implementiert.\n\n\nSonstige Anmerkungen, die Sie hinzufügen möchten:\n\nMeine `.gitmodules` waren immer eine passende Datei im gleichen Verzeichnis, um\nbei einem Merge darauf aufmerksam zu werden, das sich etwas ändert.\nBranches sind bei mir u.a Staging- Bereiche) \n```\n    .gitmodules -> symlinks zu einer dieser Dateien \n                    (abhängig zum aktuellen Branch)\n\n        -> .gitmodules_stable\n                ^ ------------------ Staging to stable, release\n        ->  .gitmodules_testing\n                ^ ------------------ Staging to testing, testing and preview\n        ->  .gitmodules_unstable\n                ^ ^ ^---<---------<-- Feature branch A\n                | +-----<---------<-- Feature branch B\n                +-------<---------<-- Feature branch C ...\n```\n\nBei einem merge unstable -> testing (-ff) würden Einstellungen von unstable\neinfach in testing mit einbezogen/übernommen werden, ohne darauf aufmerksam zu\nwerden. Was auch zur Folge hat, dass man nicht mehr darauf aufmerksam gemacht\nwird, das die Abhängigkeiten der Submodule ebenfalls angehoben werden müssen,\nbevor der merge sauber/ fertig ist.\n\nWenn an mehreren Submodulen gearbeitet wird, macht das durchaus Sinn. Gerade\ndann, wenn man eben nicht alles online hat oder haben will, um einen aktuellen\nStand zu prüfen/testen etc. bevor man dann die Hashes der Submodule bindet und\nalles dann je nach Abhängigkeit Stück für Stück öffentlich stellt.\nWas für ein Aufwand :-/\n\nMit `git` selbst (Version 2.39.0, Debian Bookworm, 2023) kann man lokal noch\nweiter arbeiten. Bei github.com ist allerdings Schluss mit lustig. Wenn es im\nRepository `git` System Dateien gibt wie `.gitignore` oder `.gitmodules` die\nSymlinks sind, verweigert github.com jegliche Arbeit, die Bugs beseitigen zu\nkönnen. Weder über das Webinterface noch via `git push --force` selbst. Uff.\n\nAlso: Nach 6 Jahren! Dazwischen gab es lokal immer wieder mal Updates, die aber\nnicht öffentlich gestellt wurden. Das Betriebssystem, ein Debian, wird etwa alle\nzwei Jahre aktualisiert. Neue `git` Versionen sind also mind. 3 Stk. seither für\ndieses Projekt dabei. Mit der aktuellen Version von `git` kann ich die Probleme\nallerdings nicht beheben. Und das ist wirklich schlecht!\n\n## Lösungsweg\n\nOption 3. war dann die Lösung. Ein Debian Wheezy (7.3) brachte eine `git` \nVersion 1.7.10.4 mit, mit der ich einen Rebase auf einen der mir bekannten und \nproblembehafteten Commits zulies. Ich bin vielleicht zu weit in die\nVergangenheit gereist, aber hiermit hatte ich erst einmal eine Basis zum testen.\nVielleicht bleibt es so und alles ist wieder gut!?\n\nDarauf folgend und, um wieder automatisch alles zu erledigen, kam mir der\ngit filter-branch wieder in den Gedanken:\n\n    git filter-branch --tree-filter 'rm -f .gitmodules' HEAD\n\nTat seinen Dienst, half aber nichts Richtung github.com als `push --force` für\ndiesen Branch.\n\n    - git filter-branch --tree-filter 'rm -f .gitmodules' HEAD\n    + git filter-branch --tree-filter 'rm -f .gitmodules'\n\nAlso: komplett und über alles bitte.\n\nDamit diese Situation aber ordentlich wird:\n\n    .gitmodules ->- symlink zum einem dieser... ->-\n    -> .gitmodules_master\n    -> .gitmodules_stable\n    -> .gitmodules_testing\n    -> .gitmodules_unstable\n\n'rm -f .gitmodules' löscht, löst aber nicht die zugrunde liegenden Bindungen der \nSubmodule. Auch hier gab es Mischungen in der Nutzung/ Verwendung, wie die\nHistorie beim genauen betrachten deutlich zeigte. Aber der Fahrplan, es so zu \nmachen, blieb einheitlich.\n\nIch habe das lokale Repository recht oft aus dem Back-up holen müssen, um dann\ndie vielen Steps von Tests wiederholen zu können...\n\nSchließlich: Submodule (`.gitmodules`) waren in der Idee immer ein Symlink.\nDamit es zukünftig für die Reparatur passt, müssen also alle symlinks in eine\nechte Datei aufgelöst werden, damit der rebase via `git filter-branch\n--tree-filter` sauber laufen kann und die Abhängigkeiten in der Basis sauber\nbleiben. Und das sieht dann wie folgt aus:\n\n    # Wenn .gitmodules ein symlink ist: \n    #   - Finde den Pfad zur echten Datei\n    #   - Lösche den Symlink\n    #   - Kopiere die echte Datei zu .gitmodules\n    git filter-branch --tree-filter \\\n        'if [ -h .gitmodules ];then loc=$(readlink .gitmodules); rm -f .gitmodules; cp $loc .gitmodules; fi;'\n    \nDamit war dieses Problem erledigt. Symlinks weg und durch den echten Inhalt\ngetauscht. Allerdings wurde nun die komplette History neu geschrieben. Lokal als\nauch die neueren `git` Versionen (Klienten und lokaler Server) meldeten\nkeinerlei Fehler mehr.\n\n# Fazit\n\nIch mag diese Funktionsweise von `git` aktuell hierzu nicht. Symlinks helfen in\nmeinem Fall. Sie sind transparent und in jedem Branch innerhalb des Repositories\nverfügbar und werden gepflegt. \n\nDas wichtigste: Sie erleichten die Arbeit da sie auf Veränderungen aufmerksam\nmachen. Das spart ungemein viel Zeit und das hinterher laufen wenn man vergisst\ndie Submodule zu korrigieren da es bei einem fast forward merge schlicht weg \nals neu = besser behandeld wird. Submudule werden im gleichen branch-Workflow\nso gebunden.\n\n\n\n\n\nBitte überprüfen Sie den restlichen Teil des Fehlerberichts unten.\nSie können jede Zeile löschen, die Sie nicht mitteilen möchten.\n\n\n[System Info]\ngit Version:\ngit version 2.39.2\ncpu: x86_64\nno commit associated with this build\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nuname: Linux 6.1.0-13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.55-1 (2023-09-29) x86_64\nCompiler Info: gnuc: 12.2\nlibc Info: glibc: 2.36\n$SHELL (typically, interactive shell): /bin/zsh\n\n\n[Aktivierte Hooks]\n\n\n\n# EN\n\n"},{"id":"484987","messageId":"20231116202718.GD1146561@coredump.intra.peff.net","threadId":"60526","inReplyTo":"CAM30mqasEjEBbn1vSUwvKP6LLjAFSw3xoeLrB1zLWnH37Z2fUg@mail.gmail.com","subject":"Re: gitmodulesSymlink .gitmodules is a symbolic link","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2023-11-16T20:27:18Z","receivedAt":"2023-11-16T20:27:19Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Nov 15, 2023 at 05:01:10PM +0100, flobee.code wrote:\n\n> But in general I think the exclusion of symlinks to git system files\n> is a mistake. It is implemented too sweepingly in my eyes.\n\nI agree that the fact that we reject these at such a low level makes it\nhard to use the tooling to rewrite the history to fix it.\n\nBut because of the security implications of out-of-tree symlinks from\nuntrusted repositories, it's important to catch these consistently. I\nsee your use case is for in-tree links, but detecting that makes the\nchecks much more complex. It also has always been the case that symlinks\ndo not behave consistently, as Git does not follow them when reading\nin-index versions of meta files.\n\n> And `git` itself also aborts. So I can't solve the problems this way.\n> \n>     git filter-branch --tree-filter 'rm -f .gitmodules' HEAD\n>     Rewrite [SomeHash] (3/185) (0 seconds passed, remaining 0 predicted) \\\n>         error: Invalid path '.gitmodules' Could not initialize the index\n\nI didn't test, but you could probably get by with using \"git replace\" to\nfirst fix up the offending trees, and then run filter-branch (though\nthere may be a lot of such trees, so you'd probably to script that\nstep). I also suspect that filter-repo would handle this better:\n\n  https://github.com/newren/git-filter-repo\n\nbut didn't try it myself.\n\n-Peff\n"}]}