{"thread":{"id":"43467","subject":"Re: handling symlinks proposal","startedAt":"2006-11-26T16:59:36Z","lastAt":"2006-11-26T19:50:01Z","messageCount":4,"participants":["René Scharfe","Christian Thaeter","Linus Torvalds"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"295943","messageId":"4569C7F8.4030303@pipapo.org","threadId":"43467","inReplyTo":null,"subject":"handling symlinks proposal","fromName":"Christian Thaeter","fromEmail":"ct@pipapo.org","sentAt":"2006-11-26T16:59:36Z","receivedAt":"2006-11-26T16:59:36Z","isPatch":false,"sender":{"key":"ct@pipapo.org","avatar":null},"body":"Git currently keep symlinks always as symlink, I would like to see some\noptional functionality when handling symlinks.\n\nSometimes it is not intended to store information external to a source\ntree in git. Problems are that it might break a checkout, just loosing\ninformation or even have security implications.\n\nWhat are are the diffrent kinds of symlinks:\n - they can point to a file local to the tree\n - or point to a file outside of the tree\n\n - they can be absolute\n - or relative\n\nhow can we handle symlinks:\n - 'keep' what git currently does, store the symlink as it is\n - 'file' store it as file (dereference it), information that it was a\n    symlink gets lost, checkouts will produce a file.\n - 'relative' store it as a relative symlink\n - 'absolute' store it as a absolute symlink\n - 'error' refuse to checkin and abort commit\n - 'warn' display a warning\n\nHow to add this to git?\nmake config options (defaults in [core] ?)\n symlink[.{local|extern}?_?{absolute|relative}?] = action\n\nper branch overrides in [branch]\n\nExample:\n[core]\n  # in-tree symlinks shall not break a checkout to another place\n  symlink.local = relative\n  # we don't want out-of-tree symlinks, store them as file\n  symlink.extern_absolute = file\n  # a relative symlink out-of-tree is likely a typo/error?\n  symlink.extern_relative = error\n\n[branch]\n  # some local feature branch keeps all symlinks\n  myfeature.symlink = keep\n\nDefault will be 'keep' so without this options it is what git currently\ndoes.\n\nAdditional thoughts:\nAn existing symlink in the tree is not altered by check in, only the\nrepository is affected.\nNew checkouts or switching branches may alter it.\nMerging between branches where one stores something as file and the\nother symlink should be straightforward, does this need to be resolved?\n\nSo far thats just an idea how I would like it. If People like it this\nway or we can refine it even better, I am going to implement it sometime\nnext.\n\n"},{"id":"294935","messageId":"4569DC1B.9080400@lsrfire.ath.cx","threadId":"43467","inReplyTo":"4569C7F8.4030303@pipapo.org","subject":"Re: handling symlinks proposal","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2006-11-26T18:25:31Z","receivedAt":"2006-11-26T18:25:31Z","isPatch":false,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Christian Thaeter schrieb:\n> Git currently keep symlinks always as symlink, I would like to see some\n> optional functionality when handling symlinks.\n> \n> Sometimes it is not intended to store information external to a source\n> tree in git. Problems are that it might break a checkout, just loosing\n> information or even have security implications.\n[...]\n> how can we handle symlinks:\n>  - 'keep' what git currently does, store the symlink as it is\n>  - 'file' store it as file (dereference it), information that it was a\n>     symlink gets lost, checkouts will produce a file.\n>  - 'relative' store it as a relative symlink\n>  - 'absolute' store it as a absolute symlink\n>  - 'error' refuse to checkin and abort commit\n>  - 'warn' display a warning\n> \n> How to add this to git?\n\nWhy would we want to?  Could you perhaps give examples on how a symlink\nin a git repo could break checkouts, cause loss of information or have\nsecurity implications?\n\nYou're symlink handling methods 'file', 'relative', 'absolute', 'error',\n'warn' aren't very useful if you check in files (and symlinks) manually,\nbecause if you add the links by hand then you can make sure they point\nto the right place (or are no symlinks, but plain files), after all.\n\nSo they're mainly intended for initial checkins and merges with external\nrepos, right?  But in these cases you have to trust foreign code anyway\n(simple example: you need to be sure 'make all' doesn't run a command\nlike 'rm -rf $HOME'), so you have to take a closer look at that stuff\nanyway -- symlinks are just one part of what needs checking.\n\nThanks,\n"},{"id":"298511","messageId":"Pine.LNX.4.64.0611261034100.3483@woody.osdl.org","threadId":"43467","inReplyTo":"4569C7F8.4030303@pipapo.org","subject":"Re: handling symlinks proposal","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-11-26T18:46:15Z","receivedAt":"2006-11-26T18:46:15Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 26 Nov 2006, Christian Thaeter wrote:\n>\n> Git currently keep symlinks always as symlink, I would like to see some\n> optional functionality when handling symlinks.\n\nI can pretty much guarantee that you really don't want to do this, and \nthat you'd be _much_ happier using some explicit wrappers around git to \nhandle your special needs, than try to teach the SCM to handle symlinks \nspecially.\n\nThe issues become all the same as with some of the idiotic things that \nother SCM's do - like $Id keyword substitution - but _much_ worse.\n\nA simple example: what is \"git diff HEAD\" supposed to say, once you've \ncommitted the symlink as something else than a symlink? It's obviously \nstill a symlink in your source tree.. Or what about \"git reset --hard\", or \n\"git checkout other-branch-that-also-had-a-symlink\"?\n\nIn other words, trivial and simple operations that have clear and \nwell-defined semantics suddenly become totally insane, with no semantics \nthat make sense what-so-ever. \n\nBy not \"keeping\" symlinks as symlinks, what you actually did was to \ntotally destroy the ability to handle symlinks AT ALL. The simplest core \noperations suddenly cannot work, because you've broken the 1:1 link \nbetween \"original source tree\" and \"tree that actually got committed\".\n\n> how can we handle symlinks:\n>  - 'keep' what git currently does, store the symlink as it is\n\nRight. This is the only sane thing, if you want to support symlinks at \nall.\n\n>  - 'file' store it as file (dereference it), information that it was a\n>     symlink gets lost, checkouts will produce a file.\n\nThis is what some other systems do, by just not knowing anything about \nsymlinks at all. It's certainly self-consistent - you can just drop all \n\"lstat()\" calls, and replace them with regular \"stat()\" calls. \n\nIt causes:\n\n - (obviously) inability to handle symlinks correctly\n\n - security problems and serious confusion when you _do_ have a symlink\n   (what happens when you check out another branch, and the symlink points \n   to outside the tree? A system that is truly unaware of symlinks will \n   generally just overwrite the file OUTSIDE the tree, which is clearly \n   bogus, but equally bogus is to just do an \"unlink + create\" which will \n   break the symlink.\n\nso it's generally MUCH worse than any alternative.\n\n>  - 'relative' store it as a relative symlink\n>  - 'absolute' store it as a absolute symlink\n\nNeither of these make any real sense. You can really only store it in the \nform it is now, because you simply _cannot_ make it a \"relative\" or \n\"absolute\" symlink (the transformation depends on how things are mounted).\n\nNot to mention that you get all the problems with \"what does 'git diff' \nmean?\" that I already alluded to above..\n\n>  - 'error' refuse to checkin and abort commit\n\nSure, we can just say \"don't allow symlinks\". This is probably what we'd \nhave to do for a native Windows client, for example, or for anything else \nthat simply doesn't support the concept (VMS port of git, anyone?).\n\n>  - 'warn' display a warning\n\nAgain, there's nothing wrong with this, but what's the point, really? \nEspecially a big enough point to merit a per-branch config option?\n\n"},{"id":"296370","messageId":"4569EFE9.6010101@pipapo.org","threadId":"43467","inReplyTo":"Pine.LNX.4.64.0611261034100.3483@woody.osdl.org","subject":"Re: handling symlinks proposal","fromName":"Christian Thaeter","fromEmail":"ct@pipapo.org","sentAt":"2006-11-26T19:50:01Z","receivedAt":"2006-11-26T19:50:01Z","isPatch":false,"sender":{"key":"ct@pipapo.org","avatar":null},"body":"Linus Torvalds wrote:\n> \n> On Sun, 26 Nov 2006, Christian Thaeter wrote:\n>> Git currently keep symlinks always as symlink, I would like to see some\n>> optional functionality when handling symlinks.\n> \n> I can pretty much guarantee that you really don't want to do this, and \n> that you'd be _much_ happier using some explicit wrappers around git to \n> handle your special needs, than try to teach the SCM to handle symlinks \n> specially.\n\nok agreed, i'll write some script which one can use on a tree to\nsanitize symlinks on given rules and/or be used as a pre-commit check.\nThat has the pretty same effect for my needs and is more sane like you\noutlined.\n\n"}]}