{"thread":{"id":"31714","subject":"Submodule design","startedAt":"2012-10-02T15:23:28Z","lastAt":"2012-10-02T17:49:36Z","messageCount":3,"participants":["Ramkumar Ramachandra","Sascha Cunz","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"200329","messageId":"CALkWK0kYh3tKXRqRO9SFMHkrytmhXFkR3yHwmiTpw6KocuLzZw@mail.gmail.com","threadId":"31714","inReplyTo":null,"subject":"Submodule design","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2012-10-02T15:23:28Z","receivedAt":"2012-10-02T15:23:28Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Hi,\n\nToday I learnt that a gitlink is a commit object embedded in a tree.\nHowever, I can't seem to be able to cat it.\n\n    $ git ls-tree HEAD\n    100644 blob 5a91f388f3648b98ae34a19ec42ba9acc7852ef4    .gitmodules\n    160000 commit 8daa12004db8862b22f6c7dd244a88ac6108b194  dotfiles\n    $ git cat-file 8daa12004db8862b22f6c7dd244a88ac6108b194\n    fatal: git cat-file 8daa12004db8862b22f6c7dd244a88ac6108b194: bad file\n\nWhy is this?  Does the object not exist in the object store at all?\nThen how was it embedded in the toplevel tree object in the first\nplace?  Also, why (how) does 'git diff' give me the impression that\nit's a blob?\n\n    $ git diff\n    diff --git a/dotfiles b/dotfiles\n    index 8daa120..ff61f40 160000\n    --- a/dotfiles\n    +++ b/dotfiles\n    @@ -1 +1 @@\n    -Subproject commit 8daa12004db8862b22f6c7dd244a88ac6108b194\n    +Subproject commit ff61f40e0938024aa3b748eb733a974b17082ec2\n\nIf it is really a blob, I should be able to stage and unstage it\nnormally, but the following command is a no-op:\n\n    $ git checkout -- dotfiles\n\nWhat is going on?  Shouldn't we get rid of these ugly inconsistencies?\n\nRam\n"},{"id":"200331","messageId":"2324506.6kHImzYEks@blacky","threadId":"31714","inReplyTo":"CALkWK0kYh3tKXRqRO9SFMHkrytmhXFkR3yHwmiTpw6KocuLzZw@mail.gmail.com","subject":"Re: Submodule design","fromName":"Sascha Cunz","fromEmail":"sascha@babbelbox.org","sentAt":"2012-10-02T15:38:31Z","receivedAt":"2012-10-02T15:38:31Z","isPatch":false,"sender":{"key":"sascha@babbelbox.org","avatar":"https://gravatar.com/avatar/14fb71bcad50c951a8c864b487f6390b89c350fc4916cf315fb5233c31e7377f?d=mp&s=160"},"body":"Am Dienstag, 2. Oktober 2012, 20:53:28 schrieben Sie:\n> Hi,\n> \n> Today I learnt that a gitlink is a commit object embedded in a tree.\n> However, I can't seem to be able to cat it.\n> \n>     $ git ls-tree HEAD\n>     100644 blob 5a91f388f3648b98ae34a19ec42ba9acc7852ef4    .gitmodules\n>     160000 commit 8daa12004db8862b22f6c7dd244a88ac6108b194  dotfiles\n>     $ git cat-file 8daa12004db8862b22f6c7dd244a88ac6108b194\n>     fatal: git cat-file 8daa12004db8862b22f6c7dd244a88ac6108b194: bad file\n> \n> Why is this?  Does the object not exist in the object store at all?\n\nCorrect. The tree entry is a pointer to the commit inside your submodule that \nshall be checked out. Obviously the submodule's commit is not part of the \nsuperproject. \nIOW: There are are actually 2 object stores: the superproject's and the \nsubmodule's. This tree entry makes a (perstiable) connection between the two.\n\n> Then how was it embedded in the toplevel tree object in the first\n> place?\nThe .gitlink for submodules has quite some special handling associated to it. \nYou can commit (and diff) it like any other blob. \n\n> Also, why (how) does 'git diff' give me the impression that\n> it's a blob?\n\n>     $ git diff\n>     diff --git a/dotfiles b/dotfiles\n>     index 8daa120..ff61f40 160000\n>     --- a/dotfiles\n>     +++ b/dotfiles\n>     @@ -1 +1 @@\n>     -Subproject commit 8daa12004db8862b22f6c7dd244a88ac6108b194\n>     +Subproject commit ff61f40e0938024aa3b748eb733a974b17082ec2\n\nSee above. Git smartly converts the \"state\" of the submodule into a one line \ntext, allowing you to \"diff 2 states of the submodule\"\n\ncd dotfiles\ngit pull # pulls some updates\ncd ..\ngit add dotfiles && git commit -m\"Update dot files to Version xxx\"\ngit push\n\nThis will record the dotfiles submodule's new HEAD SHA1 as the current one \ninside the superproject. When you now checkout the superproject to another \nlocation and do: a \"git submodule update --init\" it will clone the dotfiles \nsubmodule and checkout the exact same version that you just commited with the \nabove commit.\n\n> If it is really a blob, I should be able to stage and unstage it\n> normally, but the following command is a no-op:\n> \n>     $ git checkout -- dotfiles\n> \n> What is going on?  Shouldn't we get rid of these ugly inconsistencies?\n\nHTH,\nSascha\n"},{"id":"200351","messageId":"7vr4pg932n.fsf@alter.siamese.dyndns.org","threadId":"31714","inReplyTo":"CALkWK0kYh3tKXRqRO9SFMHkrytmhXFkR3yHwmiTpw6KocuLzZw@mail.gmail.com","subject":"Re: Submodule design","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-10-02T17:49:36Z","receivedAt":"2012-10-02T17:49:36Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> Hi,\n>\n> Today I learnt that a gitlink is a commit object embedded in a tree.\n> However, I can't seem to be able to cat it.\n>\n>     $ git ls-tree HEAD\n>     100644 blob 5a91f388f3648b98ae34a19ec42ba9acc7852ef4    .gitmodules\n>     160000 commit 8daa12004db8862b22f6c7dd244a88ac6108b194  dotfiles\n>     $ git cat-file 8daa12004db8862b22f6c7dd244a88ac6108b194\n>     fatal: git cat-file 8daa12004db8862b22f6c7dd244a88ac6108b194: bad file\n\nIs this handcrafted typescript?  You do not have \"-t\" nor \"commit\"\nafter cat-file, so you should have got the usage message.\n\nIn any case, not having the commit object available in the\nsuperproject is essential and fundamental.\n\nBinding a separate project as a submodule at a specific path in the\nsuperproject, instead of adding the tree structure as a subdirectory\nas part of the superproject, is what allows you (note this is not\n\"requires\") to work with the superproject _without_ having to\npopulate the submodule.  Imagine a submodule for the source of a\nlibrary the superproject uses and the superproject is arranged in\nsuch a way that you can build the whole thing from the source, or\nyou can use the installed library and link to it.  When doing the\nlatter, you do not have to \"submodule init\" that part.\n\nThe only thing the superproject needs to record is what specific\nstate of the submodule is meant to appear, if it is instantiated, in\nthe path.  We (primarily Linus, actually) chose to do so by\nrecording the name of the commit object from the submodule after\nconsidering other possibilities (check the list archive).\n\nAnd having to include that commit object in the superproject defeats\nthe whole point of binding a _separate_ and _independent_ project as\na submodule.  You could deliberately arrange the submodule so that\nit shares the object store with the superproject, but that is not\nthe common or default mode of operation.  Not finding an object from\nthe submodule's history in the superproject is perfectly normal.\n\n> What is going on?  Shouldn't we get rid of these ugly inconsistencies?\n\nI do not see anything ugly or inconsistent, except that the way you\nphrased your message may be unnecessarily an ugly way to show\nfrustration coming either from a lack of understanding or from a\nsimple misunderstanding.\n"}]}