{"thread":{"id":"35181","subject":"Finding the repository","startedAt":"2013-10-23T07:52:43Z","lastAt":"2013-10-25T03:09:25Z","messageCount":5,"participants":["Perry Hutchison","Duy Nguyen","Phil Hord"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"229316","messageId":"5267804b.JaxQnlQ5Cx+By4RS%perryh@pluto.rain.com","threadId":"35181","inReplyTo":null,"subject":"Finding the repository","fromName":"Perry Hutchison","fromEmail":"perryh@pluto.rain.com","sentAt":"2013-10-23T07:52:43Z","receivedAt":"2013-10-23T07:52:43Z","isPatch":false,"sender":{"key":"perryh@pluto.rain.com","avatar":null},"body":"At least in version 1.7.0.4, it seems git does not like being run\nfrom outside the repository, even if the file(s) being operated\non are inside the repository, unless it is given a pointer to the\nrepository via the --git-dir= option or the GIT_DIR enironment\nvariable.\n\nFor example, suppose /foo/bar is a local repository and baz.c is a\nfile in the outermost directory that I want to remove.  This works:\n\n  $ cd /foo/bar\n  $ git rm baz.c\n\nbut this, which intuitively should mean exactly the same thing,\nfails:\n\n  $ cd /foo\n  $ git rm bar/baz.c\n  fatal: Not a git repository (or any of the parent directories): .git\n\nI've written a wrapper script that solves this problem, but it is\nmore an illustration or proof of concept than a real \"solution\"\n-- the command line parsing may well be imperfect, and it would\nbe semantically incorrect in such cases as committing multiple\n(individually specified) files:  it would do a separate commit\nof each pathname rather than a single commit of all pathnames.\n\nHas anyone considered enhancing the automatic repository search in\ngit itself to look in the directory where the specified file(s) is/are\nlocated, as a last resort before failing?  (Yes, this does present\nthe potential for operating on multiple repositories with a single\ninvocation of git; would that be a bad thing?)\n\n--------\n\n#!/usr/local/bin/bash\n\n# smarter git:  if the current directory has no .git subdirectory\n# (i.e. is not in a repository), try running git in the directory\n# where each file is located instead of in the current directory.\n\n[ \"$1\" == \"--version\" -o \"$1\" == \"--help\" -o \"$1\" == \"--exec-path\" \\\n  -o \"x$GIT_DIR\" != \"x\" -o -d .git ] && exec git \"$@\"\n\n# Set defaults\nflags=\"\"\ndirSet=0\n\n# Collect flag params\nwhile [[ \"$1\" == -?* ]] ; do\n   case \"$1\" in\n      --git-dir=* )\n\tdirSet=1\n\t;;\n      * )\n   esac\n   flags=\"$flags $1\"\n   shift\ndone\n\n[ \"$dirSet\" == \"1\" ] && exec git $flags \"$@\"\n\n# next word must be the command\n\ngitCmd=\"$1\"\nshift\n\n# remaining words must be pathnames\n\nfor f in \"$@\"\ndo\n   ( cd $(dirname \"$f\") && git $flags $gitCmd $(basename \"$f\") )\ndone\n"},{"id":"229319","messageId":"CACsJy8DgxpjasroZv4iqTn9JhQ_3r2DD9uEf-xL-uyyPOtWh+A@mail.gmail.com","threadId":"35181","inReplyTo":"5267804b.JaxQnlQ5Cx+By4RS%perryh@pluto.rain.com","subject":"Re: Finding the repository","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2013-10-23T08:49:06Z","receivedAt":"2013-10-23T08:49:06Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Oct 23, 2013 at 2:52 PM, Perry Hutchison <perryh@pluto.rain.com> wrote:\n> At least in version 1.7.0.4, it seems git does not like being run\n> from outside the repository, even if the file(s) being operated\n> on are inside the repository, unless it is given a pointer to the\n> repository via the --git-dir= option or the GIT_DIR enironment\n> variable.\n>\n> For example, suppose /foo/bar is a local repository and baz.c is a\n> file in the outermost directory that I want to remove.  This works:\n>\n>   $ cd /foo/bar\n>   $ git rm baz.c\n>\n> but this, which intuitively should mean exactly the same thing,\n> fails:\n>\n>   $ cd /foo\n>   $ git rm bar/baz.c\n>   fatal: Not a git repository (or any of the parent directories): .git\n\nI share your pain. In my case I hate to go inside a directory just to\ngrep something. In my opinion git should be flexible and work at least\nin unambiguous cases. But it's not easy to determine ambiguity here,\nespecially when the repo finding code does not know anything about\n\"bar/barz.c\" (is it a pathname or an argument to an option?). There\nare more cases to consider, like what if you do \"git rm bar/baz.c and\nrab/zab.c\" where bar and rab are two different repositories.. And the\nsetup code is not exactly easy to add these stuff in..\n-- \nDuy\n"},{"id":"229384","messageId":"5268d0ff.HMSQf8rpwyXtEYEA%perryh@pluto.rain.com","threadId":"35181","inReplyTo":"CACsJy8DgxpjasroZv4iqTn9JhQ_3r2DD9uEf-xL-uyyPOtWh+A@mail.gmail.com","subject":"Re: Finding the repository","fromName":"Perry Hutchison","fromEmail":"perryh@pluto.rain.com","sentAt":"2013-10-24T07:49:19Z","receivedAt":"2013-10-24T07:49:19Z","isPatch":false,"sender":{"key":"perryh@pluto.rain.com","avatar":null},"body":"Duy Nguyen <pclouds@gmail.com> wrote:\n\n> ... it's not easy to determine ambiguity here, especially when the\n> repo finding code does not know anything about \"bar/barz.c\" (is it\n> a pathname or an argument to an option?).\n\nIOW, the code that finds the repository is called \"too early\"?\n\nOne way to solve that to that would be to proceed, even if the\nrepository has to be left as \"unknown\" until it actually needs to\nbe consulted -- by which time the subcommand would presumably have\nparsed all of the options and pathnames and so would know which is\nwhich.  Then, use the pathname(s) to identify the repository(ies).\nYes, if there's more than one repository involved, the subcommand\nhas to do a \"for each repository\" loop.  The code to do all this\ncould go in a module shared among the subcommands.\n\n> There are more cases to consider, like what if you do\n> \"git rm bar/baz.c and rab/zab.c\" where bar and rab are\n> two different repositories..\n\nSo we remove baz.c from bar and zab.c from rab.  It's not clear\nto me that there's anything wrong with that -- it's exactly what\nI would expect to have happen (and also what the hackish script\nI posted will do).\n"},{"id":"229400","messageId":"CACsJy8AVdV8nPXFVdj37O1dgvcWh=tQ5C7iUE134Wk2yTD42Ug@mail.gmail.com","threadId":"35181","inReplyTo":"5268d0ff.HMSQf8rpwyXtEYEA%perryh@pluto.rain.com","subject":"Re: Finding the repository","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2013-10-24T13:46:33Z","receivedAt":"2013-10-24T13:46:33Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Oct 24, 2013 at 2:49 PM, Perry Hutchison <perryh@pluto.rain.com> wrote:\n> Duy Nguyen <pclouds@gmail.com> wrote:\n>\n>> ... it's not easy to determine ambiguity here, especially when the\n>> repo finding code does not know anything about \"bar/barz.c\" (is it\n>> a pathname or an argument to an option?).\n>\n> IOW, the code that finds the repository is called \"too early\"?\n\nYes. First it tries to find and setup the repository. Read per-config\nrepo file and add aliases to the database if any. Resolve alias. Run\nthe actual command. Then the command parses the command line.\n\n> One way to solve that to that would be to proceed, even if the\n> repository has to be left as \"unknown\" until it actually needs to\n> be consulted -- by which time the subcommand would presumably have\n> parsed all of the options and pathnames and so would know which is\n> which.  Then, use the pathname(s) to identify the repository(ies).\n> Yes, if there's more than one repository involved, the subcommand\n> has to do a \"for each repository\" loop.  The code to do all this\n> could go in a module shared among the subcommands.\n\nThat breaks the normal process I described above (i.e. lots of code\nchanges). People would scream at the code changes for a minor\nconvenience. We could refactor the parsing code so that the startup\ncode could do a \"dry-run\" command line parsing pass first. May work\nfor the majority of commands that do not need special parsing\ncallbacks.\n\nEven then we still need more changes because git does not work well if\ncwd is outside the worktree. Paths like 'bar/baz.c\" need to cut \"bar/\"\nout. Then if \"baz.c\" is to printed out again, \"bar/\" needs to be\nprepended back..\n\n>> There are more cases to consider, like what if you do\n>> \"git rm bar/baz.c and rab/zab.c\" where bar and rab are\n>> two different repositories..\n>\n> So we remove baz.c from bar and zab.c from rab.  It's not clear\n> to me that there's anything wrong with that -- it's exactly what\n> I would expect to have happen (and also what the hackish script\n> I posted will do).\n\nFor \"git rm\", maybe. Many other commands need repo information and it\nwould not make sense to have paths from two different repositories.\nFor example, commit, rev-list or log. And it may break more things as\nmost of current commands are designed to work on one repo from a to z.\nSome may support multi-repo operations if they're part of submodule\nsupport.\n-- \nDuy\n"},{"id":"229459","messageId":"CABURp0rFPYZEDC95+pL7bvnFuMpsiqp_YoQJ6f0DSFYWP=v4Gw@mail.gmail.com","threadId":"35181","inReplyTo":"CACsJy8AVdV8nPXFVdj37O1dgvcWh=tQ5C7iUE134Wk2yTD42Ug@mail.gmail.com","subject":"Re: Finding the repository","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2013-10-25T03:09:25Z","receivedAt":"2013-10-25T03:09:25Z","isPatch":false,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"On Thu, Oct 24, 2013 at 9:46 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Thu, Oct 24, 2013 at 2:49 PM, Perry Hutchison <perryh@pluto.rain.com> wrote:\n>> Duy Nguyen <pclouds@gmail.com> wrote:\n>>\n>>> ... it's not easy to determine ambiguity here, especially when the\n>>> repo finding code does not know anything about \"bar/barz.c\" (is it\n>>> a pathname or an argument to an option?).\n...\n>>> There are more cases to consider, like what if you do\n>>> \"git rm bar/baz.c and rab/zab.c\" where bar and rab are\n>>> two different repositories..\n>>\n>> So we remove baz.c from bar and zab.c from rab.  It's not clear\n>> to me that there's anything wrong with that -- it's exactly what\n>> I would expect to have happen (and also what the hackish script\n>> I posted will do).\n>\n> For \"git rm\", maybe. Many other commands need repo information and it\n> would not make sense to have paths from two different repositories.\n> For example, commit, rev-list or log. And it may break more things as\n> most of current commands are designed to work on one repo from a to z.\n> Some may support multi-repo operations if they're part of submodule\n> support.\n\nI've done some preliminary work on extending this sort of behavior to\nsubmodule commands.  For example,\n\n  git grep --recurse-submodules foo\n\nwhich would look in the current project path and also any submodules\nencountered.  This usage also begs for this extension:\n\n  git grep --recurse-submodules foo path/to/sub/bar.c\n\nWhere 'path/to/sub' is a submodule, and therefore a foreign git repo\nto this one.  Solving this is a little bit easier than your case\nbecause git is already running inside a repo. Extending the reach to\nsubmodules only requires more odb's than our first one to be\nconsidered.  Along the way, I have considered your case, but I haven't\nfocused on it. Lately I haven't had time to focus on my case either,\nthough.  :-\\\n\nPhil\n"}]}