{"thread":{"id":"16182","subject":"[RFC] Referring to a submodule state recorded in a supermodule from within the submodule","startedAt":"2008-11-05T17:24:28Z","lastAt":"2008-11-05T20:45:03Z","messageCount":4,"participants":["Johan Herland","Junio C Hamano","Daniel Barkalow"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"94977","messageId":"200811051824.28374.johan@herland.net","threadId":"16182","inReplyTo":null,"subject":"[RFC] Referring to a submodule state recorded in a supermodule from within the submodule","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2008-11-05T17:24:28Z","receivedAt":"2008-11-05T17:24:28Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"Hi,\n\nI have a stand-alone project, \"foo\", that I work on myself. The \"foo\" \nproject is included as a submodule in two other projects, \"bar\" \nand \"baz\", that I don't have any direct affiliation with.\n\nSemi-regularly, I like to keep tabs on bar and baz, to see what versions \nof foo they are using, what changes they have made to foo, and if there \nare things I could pick up from them, or maybe even things they could \nlearn from eachother.\n\nDoing this currently is quite tedious:\n1. Clone/Fetch bar and initialize/update its foo submodule\n2. Clone/Fetch baz and initialize/update its foo submodule\n3. Set up remotes bar_foo and baz_foo in my main foo repo,\n   pointing to bar/foo and baz/foo, respectively. Fetch.\n4. Create tags bar_foo_current and baz_foo_current pointing\n   to the foo SHA1 sum recorded in baz and baz, respectively.\n5. Start comparing bar_foo_current and baz_foo_current to\n   eachother, and to my own master branch.\n\n\nNow, bring this into a larger company setting. There are many (~100) \ndifferent foo-type projects owned by (~50) different developers. These \nprojects are included as submodules by several (~20) different \nbar/baz-type projects. In addition, each bar/baz-type project has \nmultiple (~3) branches using various versions of the foo-type \nsubmodules.\n\nFinally, throw in questions like \"What are the differences in submodule \nFOO between branch X of BAR, and branch Y of BAZ?\", for random values \nof FOO, X, BAR, Y, and BAZ. It is apparent that the above approach just \ndoesn't cut it.\n\nIronically, these questions are fairly easily answered by our current \nCVS setup (which applies the supermodule tags/branches to the entire \nsource tree (including submodules)):\n1. cd FOO\n2. cvs diff -r BAR_X -r BAZ_Y\n\nWhat I'd like, is some way to refer to the state of a repo as specified \nby the appropriate submodule blob in a superproject commit. Ideally \nthis should be done remotely as well, so that I don't have to clone the \nentire superproject just to get at the appropriate submodule blob.\n\n\nCrude Proposal:\n\nDefine a new \"git submodule\" subcommand that takes three arguments:\n   <superURL> <tree-ish> <submoduleName>\nThe command does the following steps:\n1. Locate git repo at <superURL>\n2. Resolve <tree-ish> to the tree object within the git repo in #1\n3. Locate .gitmodules within the tree object in #2\n4. Lookup <submoduleName> in .gitmodules to find its path and URL\n5. Locate the submodule blob from the path in #4 within the tree from #2\n6. Record the object name (SHA1) stored in the submodule blob from #4\n7. Fetch the object name (#7) from the submodule repo (its URL was\n   found in #4) into the local git repo\n8. Store a reference to the fetched object\n\n\nGiven the above command, the tedious steps described at the top can be \nreduced to the following (which is reasonably close to the equivalent \nCVS commands):\n1. git submodule magic-command url/to/bar master foo\n2. git submodule magic-command url/to/baz master foo\n3. Start comparing the fetched refs to eachother, and\n   to my own master branch.\n\nIf this sounds reasonable, I'd be happy to start coding the above \nproposal.\n\n\nHave fun! :)\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"94980","messageId":"7vhc6mkqxb.fsf@gitster.siamese.dyndns.org","threadId":"16182","inReplyTo":"200811051824.28374.johan@herland.net","subject":"Re: [RFC] Referring to a submodule state recorded in a supermodule from within the submodule","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-11-05T17:45:20Z","receivedAt":"2008-11-05T17:45:20Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johan Herland <johan@herland.net> writes:\n\n> I have a stand-alone project, \"foo\", that I work on myself. The \"foo\" \n> project is included as a submodule in two other projects, \"bar\" \n> and \"baz\", that I don't have any direct affiliation with.\n>\n> Semi-regularly, I like to keep tabs on bar and baz, to see what versions \n> of foo they are using, what changes they have made to foo, and if there \n> are things I could pick up from them, or maybe even things they could \n> learn from eachother.\n>\n> Doing this currently is quite tedious:\n> 1. Clone/Fetch bar and initialize/update its foo submodule\n> 2. Clone/Fetch baz and initialize/update its foo submodule\n\nIf I am reading you right and you are only interested in the part \"foo\" in\nthese projects, there is something wrong with the setup of \"bar\" and \"baz\".\n\nThe submodule mechanism is designed to bind an independent project on its\nown as a subdirectory of another project.  It seems to me that the problem\nis that \"bar\" and \"baz\" projects do not give direct access to clone \"foo\"\npart of them for you or other people.\n"},{"id":"94984","messageId":"200811051909.51970.johan@herland.net","threadId":"16182","inReplyTo":"7vhc6mkqxb.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC] Referring to a submodule state recorded in a supermodule from within the submodule","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2008-11-05T18:09:51Z","receivedAt":"2008-11-05T18:09:51Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Wednesday 05 November 2008, Junio C Hamano wrote:\n> Johan Herland <johan@herland.net> writes:\n> > I have a stand-alone project, \"foo\", that I work on myself. The\n> > \"foo\" project is included as a submodule in two other projects,\n> > \"bar\" and \"baz\", that I don't have any direct affiliation with.\n> >\n> > Semi-regularly, I like to keep tabs on bar and baz, to see what\n> > versions of foo they are using, what changes they have made to foo,\n> > and if there are things I could pick up from them, or maybe even\n> > things they could learn from eachother.\n> >\n> > Doing this currently is quite tedious:\n> > 1. Clone/Fetch bar and initialize/update its foo submodule\n> > 2. Clone/Fetch baz and initialize/update its foo submodule\n>\n> If I am reading you right and you are only interested in the part\n> \"foo\" in these projects, there is something wrong with the setup of\n> \"bar\" and \"baz\".\n>\n> The submodule mechanism is designed to bind an independent project on\n> its own as a subdirectory of another project.  It seems to me that\n> the problem is that \"bar\" and \"baz\" projects do not give direct\n> access to clone \"foo\" part of them for you or other people.\n\nNo, they do. I can clone foo directly from bar/baz's server. The problem \nis that I cannot quickly get at which revision of foo is used by \nbar/baz without tedious cloning and interacting with the superrepos.\n\nI basically want to quickly answer questions like \"What are the \ndifferences between bar's foo and baz's foo (and my own foo)?\"\n\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"94995","messageId":"alpine.LNX.1.00.0811051522480.19665@iabervon.org","threadId":"16182","inReplyTo":"200811051824.28374.johan@herland.net","subject":"Re: [RFC] Referring to a submodule state recorded in a supermodule from within the submodule","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-11-05T20:45:03Z","receivedAt":"2008-11-05T20:45:03Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Wed, 5 Nov 2008, Johan Herland wrote:\n\n> Hi,\n> \n> I have a stand-alone project, \"foo\", that I work on myself. The \"foo\" \n> project is included as a submodule in two other projects, \"bar\" \n> and \"baz\", that I don't have any direct affiliation with.\n> \n> Semi-regularly, I like to keep tabs on bar and baz, to see what versions \n> of foo they are using, what changes they have made to foo, and if there \n> are things I could pick up from them, or maybe even things they could \n> learn from eachother.\n> \n> Doing this currently is quite tedious:\n> 1. Clone/Fetch bar and initialize/update its foo submodule\n> 2. Clone/Fetch baz and initialize/update its foo submodule\n> 3. Set up remotes bar_foo and baz_foo in my main foo repo,\n>    pointing to bar/foo and baz/foo, respectively. Fetch.\n> 4. Create tags bar_foo_current and baz_foo_current pointing\n>    to the foo SHA1 sum recorded in baz and baz, respectively.\n> 5. Start comparing bar_foo_current and baz_foo_current to\n>    eachother, and to my own master branch.\n\nSet up remotes in your foo:\n\n[remote \"bar\"]\n\turl = ...\n\tfetch = refs/heads/*:refs/remotes/bar/*\n[remote \"bar-foo\"]\n\turl = ...\n\tfetch = refs/heads/*:refs/remotes/in-bar/*\n\nYou should be able to do \"git fetch bar\" (you really don't want to merge \nthis, but git is fine with unrelated histories in the same repo...);\n\"git fetch bar-foo\".\n\nThen I'd expect \"git log master..bar/master:foo\" to work [*1*].\n\nbar/master is the commit in the superproject, \"foo\" is the path in its \ntree that reaches the submodule, so \"bar/master:foo\" is whatever's there, \nwhich turns out to be a commit, which is the commit you're interested in.\n\nI think the only annoying things are that you need to find out from \nbar/master:.gitmodules what to fetch as the branch that's related to your \nlocal project, and you need to do two fetches each time, and you have to \ndownload the whole superproject state in order to find out one reference \nfrom it. (But this also lets you look at the history of which versions \nthey incorporated over time, so you can see \"they adopted something at one \npoint, rolled back for a while, cherry-picked a change, and then updated \nto a version with the feature fixed.\")\n\n[*1*] This may not actually work; I don't know if we give up on \ninterpreting a object name when we're looking for a commit and start to \nsee a path. I'm pretty sure that git will not understand \n\"refs/remotes/bar/master:path/to/foo:Makefile\" (which could name the \nMakefile in the root directory of the commit in the path/to/foo location \nin the current value of bar/master, but will actually look for a \n\"foo:Makefile\" filename; it probably ought to work with a '/' before the \nsecond ':', though, since that is unambiguous)\n\n\t-Daniel\n*This .sig left intentionally blank*\n"}]}