{"thread":{"id":"59520","subject":"Add a way to disable «git clean» per repo","startedAt":"2023-04-01T21:31:15Z","lastAt":"2023-04-10T13:34:42Z","messageCount":4,"participants":["Guillem Jover","Junio C Hamano","Thomas Guyot"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"474651","messageId":"ZCiZCM+AAUnjp4Ml@thunder.hadrons.org","threadId":"59520","inReplyTo":null,"subject":"Add a way to disable «git clean» per repo","fromName":"Guillem Jover","fromEmail":"guillem@hadrons.org","sentAt":"2023-04-01T20:50:16Z","receivedAt":"2023-04-01T21:31:15Z","isPatch":false,"sender":{"key":"guillem@hadrons.org","avatar":null},"body":"Hi!\n\n[ I initially filed this in the Debian bug tracking system as it\n  seemed to me that filing a feature request on a mailing list had\n  a great potential to get lost. But I guess I can try anyway. :) ]\n\nFor repositories that are not tracking code, say when storing your ~/\nunder git, or to store say collections of data files such as photos,\ntexts or similar, you might end up using .gitignore to unclutter\n«git status». The problem is that both ignored and non-ignored\nuntracked files can be “precious”, as in not version-tracked by losing\nthem might imply data loss.\n\nAccidentally running «git clean -xdf» or «git clean -Xdf» might be\ncatastrophic there. But for the ~/ case (or any such tracking in a\nparent of git trees, this is even worse, as an accidental «cd» too\nmuch while in some code repo might end up accidentally recursively\nrunning those «git clean» on an unexpected working tree and all of\nits subdirectories (except for other git working trees).\n\nI tend to be rather careful with this, but I recently had a scare\nwhere this happened to me, and lost a few (not essential) files before\nI noticed and Ctrl-C'd git. I then set out to try to disable git clean\non these situations, but I see no way to do that as aliases do not work\nwith built-ins, and adding a ~/bin/git wrapper to check for this seems\nextremely cumbersome.\n\nIt would thus be nice if there was an option that could be set to\ncompletely disable «git clean» on a repo. I guess it might make sense\nto disable for any untracked file, or perhaps for ignored and/or\nnon-ignored. So that these kind of work trees could be protected.\n\nThanks,\nGuillem\n"},{"id":"474698","messageId":"xmqq355g6f6u.fsf@gitster.g","threadId":"59520","inReplyTo":"ZCiZCM+AAUnjp4Ml@thunder.hadrons.org","subject":"Re: Add a way to disable «git clean» per repo","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-04-03T17:36:25Z","receivedAt":"2023-04-03T17:36:31Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Guillem Jover <guillem@hadrons.org> writes:\n\n> Accidentally running «git clean -xdf» or «git clean -Xdf» might be\n> catastrophic there.\n\nSo would accidentally running \"rm -fr\" there be catastrophic, too.\nI doubt it would make much sense to file a feature request to Debian\nor GNU/FSF to disable \"rm -r\" in certain directories.  I am not sure\nwhy \"git clean\" should be any different.\n\nCommands like \"git clean\" require \"-f\" before they become overly\ndestructuve for a reason.  clean.requireForce defaults to true for\nthe same reason.\n"},{"id":"475052","messageId":"ZDLvUxp0d33VgFQY@thunder.hadrons.org","threadId":"59520","inReplyTo":"xmqq355g6f6u.fsf@gitster.g","subject":"Re: Add a way to disable «git clean» per repo","fromName":"Guillem Jover","fromEmail":"guillem@hadrons.org","sentAt":"2023-04-09T17:01:07Z","receivedAt":"2023-04-09T17:02:29Z","isPatch":false,"sender":{"key":"guillem@hadrons.org","avatar":null},"body":"Hi!\n\nOn Mon, 2023-04-03 at 10:36:25 -0700, Junio C Hamano wrote:\n> Guillem Jover <guillem@hadrons.org> writes:\n> > Accidentally running «git clean -xdf» or «git clean -Xdf» might be\n> > catastrophic there.\n> \n> So would accidentally running \"rm -fr\" there be catastrophic, too.\n\nSure.\n\n> I doubt it would make much sense to file a feature request to Debian\n> or GNU/FSF to disable \"rm -r\" in certain directories.  I am not sure\n> why \"git clean\" should be any different.\n\nRight, but I see a substantial difference though, «git clean» is\npart of the git toolset to manage among other things specific work\ntrees, where that behavior is controlled through configuration, and\nis as such confined within those specific realms, where also the\nproperties of what is being tracked might be different.\n(With GNU coreutils rm you can confine it within one filesystem with\n--one-file-system, but TBH I've never had the need to use it AFAIR,\nand it's not enabled by default.)\n\n> Commands like \"git clean\" require \"-f\" before they become overly\n> destructuve for a reason.  clean.requireForce defaults to true for\n> the same reason.\n\nRight, I guess that's another reason for me why I see these («rm» vs\n«git clean») as not being entirely comparable. Using «rm» requires in\nmost cases no force options, even when removing recursively (with -r),\nwhile «git clean» by default will fail fatally (for all invocations\nAFAICS?), so perhaps I'm holding it wrong, but when you end up invoking\na command very often (f.ex. to make sure your project is building from\na clean state), which requires using a force option (because passing -i\nwould become very cumbersome very quick), that becomes a habit or part\nof your muscle-memory (perhaps a bad one), that means I tend to not pay\nas much attention as I'd do when running «rm -rf» (also because of the\nconfinement I mentioned above).\n\nFor now it occurred to me that I could create dummy git repos in\nparent directories to act as «git clean» barriers, so that it does not\npropagate further up in the directory tree, but that still seems like\na hack, and I'd really like to protect specific work trees where I know\nI never want to be able to run «git clean».\n\nThanks,\nGuillem\n"},{"id":"475061","messageId":"37127bb2-8fa2-5908-6824-bb9be9bb0c3b@gmail.com","threadId":"59520","inReplyTo":"ZDLvUxp0d33VgFQY@thunder.hadrons.org","subject":"Re: Add a way to disable «git clean» per repo","fromName":"Thomas Guyot","fromEmail":"tguyot@gmail.com","sentAt":"2023-04-10T13:32:26Z","receivedAt":"2023-04-10T13:34:42Z","isPatch":false,"sender":{"key":"tguyot@gmail.com","avatar":"https://avatars.githubusercontent.com/u/403890?v=4"},"body":"On 2023-04-09 13:01, Guillem Jover wrote:\n>> I doubt it would make much sense to file a feature request to Debian\n>> or GNU/FSF to disable \"rm -r\" in certain directories.  I am not sure\n>> why \"git clean\" should be any different.\n> Right, but I see a substantial difference though, «git clean» is\n> part of the git toolset to manage among other things specific work\n> trees, where that behavior is controlled through configuration, and\n> is as such confined within those specific realms, where also the\n> properties of what is being tracked might be different.\n> (With GNU coreutils rm you can confine it within one filesystem with\n> --one-file-system, but TBH I've never had the need to use it AFAIR,\n> and it's not enabled by default.)\n>\n\nHi Guillem,\n\nI agree with Junio here - there are many ways you could adapt your use \nof Git to safely manage these types of repos... for starters I don't \nlike storing the .git directly in the folders I'm tracking, I always use \nseparate repos with a script to compare the contents vs the real \nfilesystem. Something like:\n\n\n#!/bin/sh\ndiff -ur `hostname -s`/ / |grep -v \"^Only in /\"\n\n\nIn this example the repo tracks files from / on multiple hosts using \nhostname as the first component; diff won't descend into \"new\" dirs so \nthis runs very fast too, and can be piped to diffstat to get a summary \nof changed files.\n\n\nAlso if you fear accidentally recalling a dangerous clean command from \nhistory, you can set HISTCONTROL=ignoreboth then prefix any dangerous \ncommand with a space, or use HISTIGNORE to selectively ignore got clean \ncommands. That works with other dangerous commands like sudo reboot, rm \n-rf, etc...\n\n\nThe HISTCONTROL way is even better imho as I would always save/recall \nthe command with -n appended (no-op) to review what would be done (ex \nsometimes there could be a virtualenv in the way that I forgot to remove \nfrom ignores) and only when I'm happy I'd remove the -n and insert a \nspace in front so the command doesn't get saved.\n\nRegards,\n\n-- \nThomas\n"}]}