{"thread":{"id":"57956","subject":"git bug: Including a git repository in a directory","startedAt":"2022-06-06T06:01:38Z","lastAt":"2022-06-06T17:10:58Z","messageCount":3,"participants":["Steven Jonn Edlefsen","René Scharfe","Glen Choo"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"456704","messageId":"e308be58-a399-8e5c-36a8-96d3d58caff3@sprangle.com","threadId":"57956","inReplyTo":null,"subject":"git bug: Including a git repository in a directory","fromName":"Steven Jonn Edlefsen","fromEmail":"steve@sprangle.com","sentAt":"2022-06-06T05:43:56Z","receivedAt":"2022-06-06T06:01:38Z","isPatch":false,"sender":{"key":"steve@sprangle.com","avatar":null},"body":"Git cannot commit/push a directory with a git repository in\na sub-directory.\n\nThe sub-directory with the git repository and the directories below\nare set to the “master” branch, while the directories above remain\nset to the new branch.\n\nWhen the top directory is committed, the sub-directory with the\ngit repository appears as an empty file.\n\nEven when the subdirectory branch name is changed from master\nto the new branch and the top directory is re-commited/pushed,\nthe same problem occurs.\n\nWhen the git repository in the sub-directory is removed, e.g.\nthe .git file is removed, and top directory is committed/pushed,\nthe subdirectory has all the sub-directories and files.\n\nSteve Edlefsen\n\n"},{"id":"456710","messageId":"24022c08-ed58-8157-6036-6a4c6a49f195@web.de","threadId":"57956","inReplyTo":"e308be58-a399-8e5c-36a8-96d3d58caff3@sprangle.com","subject":"Re: git bug: Including a git repository in a directory","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2022-06-06T11:00:48Z","receivedAt":"2022-06-06T11:01:01Z","isPatch":false,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 06.06.22 um 07:43 schrieb Steven Jonn Edlefsen:\n> Git cannot commit/push a directory with a git repository in\n> a sub-directory.\n>\n> The sub-directory with the git repository and the directories below\n> are set to the “master” branch, while the directories above remain\n> set to the new branch.\n>\n> When the top directory is committed, the sub-directory with the\n> git repository appears as an empty file.\n>\n> Even when the subdirectory branch name is changed from master\n> to the new branch and the top directory is re-commited/pushed,\n> the same problem occurs.\n>\n> When the git repository in the sub-directory is removed, e.g.\n> the .git file is removed, and top directory is committed/pushed,\n> the subdirectory has all the sub-directories and files.\n\nThis is intended behavior.  A repository inside another one needs\nspecial handling.  Git provides the submodule feature for that.  A\nsimpler alternative for some use cases is called subtree.\n\nThat's all I can tell you, as I haven't used submodules and subtrees\nmyself.  At least I hope these keywords help you explore your options.\nOthers will probably chime in with advise on which one to use if you\nexplain _why_ you want to combine multiple repositories.\n\nRené\n"},{"id":"456725","messageId":"kl6ly1y9d91t.fsf@chooglen-macbookpro.roam.corp.google.com","threadId":"57956","inReplyTo":"24022c08-ed58-8157-6036-6a4c6a49f195@web.de","subject":"Re: git bug: Including a git repository in a directory","fromName":"Glen Choo","fromEmail":"chooglen@google.com","sentAt":"2022-06-06T16:57:18Z","receivedAt":"2022-06-06T17:10:58Z","isPatch":false,"sender":{"key":"glencbz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58092771?v=4"},"body":"Hi!\n\nRené Scharfe <l.s.r@web.de> writes:\n\n> Am 06.06.22 um 07:43 schrieb Steven Jonn Edlefsen:\n>> Git cannot commit/push a directory with a git repository in\n>> a sub-directory.\n>>\n>> The sub-directory with the git repository and the directories below\n>> are set to the “master” branch, while the directories above remain\n>> set to the new branch.\n>>\n>> When the top directory is committed, the sub-directory with the\n>> git repository appears as an empty file.\n>>\n>> Even when the subdirectory branch name is changed from master\n>> to the new branch and the top directory is re-commited/pushed,\n>> the same problem occurs.\n>>\n>> When the git repository in the sub-directory is removed, e.g.\n>> the .git file is removed, and top directory is committed/pushed,\n>> the subdirectory has all the sub-directories and files.\n>\n> This is intended behavior.  A repository inside another one needs\n> special handling.  Git provides the submodule feature for that.  A\n> simpler alternative for some use cases is called subtree.\n\nAs René described, this is intended behavior - repositories cannot\ncontain entire repositories with `.git` inside them [1]. As far as I\nknow, this is security feature because `.git` can contain sensitive\nfiles that you wouldn't want to clone down, e.g. .git/config can make\n\"git\" execute arbitrary code.\n\nWhat happened in your case is that Git noticed that the subdirectory is\na repository and automatically 'sanitizes' it for you by converting it\ninto (what is essentially) a submodule [2]. When a subdirectory is a\nsubmodule, Git stores a single commit id for the entire subdirectory -\nyou you can no longer change individual files inside the subdirectory.\n\nTo demonstrate this \"single commit id\" behavior, this is what happens if\nyou tried to `git init` a subdirectory in an existing project:\n\n  $ git init foo\n  Initialized empty Git repository in /Users/chooglen/Code/repo/foo/.git/\n  $ git add foo\n  error: 'foo/' does not have a commit checked out\n\nNotice the line above! We can't add `foo` because it has been converted\ninto a (pseudo) submodule [2].\n\n  $ (cd foo && git commit -m \"foo\" --allow-empty) # create a commit\n  [main (root-commit) 9e27581] foo\n  $ git add foo\n  warning: adding embedded git repository: foo\n  hint: You've added another git repository inside your current repository.\n  hint: Clones of the outer repository will not contain the contents of\n  hint: the embedded repository and will not know how to obtain it.\n  hint: If you meant to add a submodule, use:\n  hint:\n  hint:   git submodule add <url> foo\n  hint:\n  hint: If you added this path by mistake, you can remove it from the\n  hint: index with:\n  hint:\n  hint:   git rm --cached foo\n  hint:\n  hint: See \"git help submodule\" for more information.\n  $ git diff HEAD \n  diff --git a/foo b/foo\n  new file mode 160000\n  index 0000000..9e27581\n  --- /dev/null\n  +++ b/foo\n  @@ -0,0 +1 @@\n  +Subproject commit 9e27581b9eb91c0f1699eb18a2e81d758de9209d\n\nNow that there is a commit in the subdirectory repository we can `git\nadd` it, but only as an entire commit. We cannot just add individual\nfiles.\n\nIf you truly need a repository inside of another repository. You may\nwant to consider submodules/subtrees as René mentioned.\n\n[1] A repository can contain a \"bare\" repository because a bare\nrepository does not have `.git`, but that isn`t relevant to the\ndiscussion here.\n[2] A submodule technically also has to have an entry in the .gitmodules\nfile.\n"}]}