1

I need a local repository for tracking my changes and a remote repository containing just some of these files.

I added a parent directory to the project to initialize a local repository and initialized another git in the project dir as another remote repository and published it to GitHub.

.gitignore file of parent repo is empty but .gitignore in child excludes all fies except some specific ones. Parent repository should not use .gitignore file of the child repo.

I need local repository to track all files and a remote repository to track just some of them. The problem is that parent repository does not include anything inside the project.

I tried this submodule solution but it creates a new folder for new repository instead of using existing one.

This is output of git add -A for parent repository:

 git add -A
warning: adding embedded git repository: Part Project Manager
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint:
hint:   git submodule add <url> Part Project Manager
hint:
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint:
hint:   git rm --cached Part Project Manager
hint:
hint: See "git help submodule" for more information.
rostamiani
  • 2,859
  • 7
  • 38
  • 74
  • I didn't understand the problem. 1) You want the parent repo to track changes in parent and child directories? 2) What do you mean by ```parent repository does not include anything inside the project.```? – Fred Guth Jul 29 '18 at 03:49
  • Yes, exactly. In fact I need local repository to track all files and a remote repository to track just some of them – rostamiani Jul 29 '18 at 03:58

1 Answers1

0

Edit, per submodule related question

You can nest repositories. Here is an example—my Git version is slightly different from yours—on this particular machine it's currently 2.14.1—but I get the same new git add complaint and behavior, which requires a little initial trickery.

$ mkdir trepo
$ cd trepo
$ git init
Initialized empty Git repository in ...
$ echo testing nested dirs > README
$ git add README
$ git commit -m initial
[master (root-commit) 1eb37c9] initial
 1 file changed, 1 insertion(+)
 create mode 100644 README

The top level repository (path/trepo) now exists, with one commit in it. The lone commit contains one file, README.

$ mkdir sub
$ cd sub
$ git init
Initialized empty Git repository in .../trepo/sub/.git
$ echo this is a nested subdirectory > README
$ git add README 
$ git commit -m initial-sub
[master (root-commit) 943378a] initial-sub
 1 file changed, 1 insertion(+)
 create mode 100644 README

The sub-repository now exists, also with one commit that contains one file named README. If we now walk back up one level, we can convince Git to add the files inside sub. However, as you found, a sufficiently modern Git—I'm not sure when this new behavior appeared—will, if we use git add sub, add sub as a submodule—well, add it as a broken submodule—rather than adding the files contained within sub. So instead of git add sub, we will explicitly add the files within sub, for each such file (which is easy now as there is only one—remember, we want to skip over the .git directory and all its contents):

$ cd ..
$ git add sub/README
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   sub/README

Let's go ahead and commit this, then make another file in sub to see what happens:

$ git commit -m 'add sub/README'
[master a7fb248] add sub/README
 1 file changed, 1 insertion(+)
 create mode 100644 sub/README
$ echo another test > sub/newfile
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        sub/newfile

nothing added to commit but untracked files present (use "git add" to track)
$ (cd sub; git status)
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        newfile

nothing added to commit but untracked files present (use "git add" to track)

So now that our trepo/.git repository is tracking files within sub, things work the way we might expect.

As I noted in comments, you can do all of this. I have seen people try this method. They usually end up unsatisfied. Still, if it works for you, well, Git is a tool, not a solution; use it however you like!

(Note that when using submodules, the "top level" repository—Git calls this the superproject—will not contain the same content as the sub-repository. Instead, each commit within the superproject will contain, in each commit, a special Git entry called a gitlink that records the correct hash ID that Git should git checkout in the submodule. The submodule is a completely independent Git repository, all on its own, that you can use as a standalone project. To use it with the superproject, you clone the superproject, then have Git use the superproject's .gitmodules file to know how to clone the submodule. After that, each existing commit you extract from the superproject knows which commit to extract in the subproject, and each new commit you make in the superproject shall record the correct subproject commit. It's up to you to make sure that those new superproject commits do record the correct subproject commit.)

Original answer below


This is not going to work the way you want. Repositories don't hold files—well, not directly. Repositories hold commits. If you connect two repositories, what they will share is some set of commits.

Any given commit holds a snapshot (of files), so in that particular sense, a repository does hold files. But it holds them one commit at a time. In general, you git checkout an entire commit. Let's call this commit C1. This fills in your work-tree, and, very importantly, also fills in your index / staging-area.1 Your work-tree now has all the files that are in C1.

If you then switch from that commit to some other commit C2, Git removes any files that went with C1 that are not in C2. Your index and work-tree now match commit C2, not commit C1.

Pay no attention to .gitignore at this point, because it's largely irrelevant. The set of tracked files, in a Git work-tree, are those files that are in the index. They exist in the index because you extracted them from commit C1 or C2, whichever it is that you checked out. So those files are tracked, and any other files in your work-tree—however they may have arrived there—are untracked.

What .gitignore does is keep Git from complaining about the untracked files. Normally, Git would whine at you, suggesting that you add them to the next commit you will make. So if you have a bunch of build artifacts, for instance, you can list them in .gitignore and keep Git from whining. As a pleasant side effect, this also means that git add . or git add --all won't add the untracked files—but their "untracked-ness" is a result of them not being in the index right now.

If you git checkout some other commit C3 that has some other set of files in it, Git will remove from the work-tree any tracked file that isn't in C3, and add—to both index and work-tree—any files that are in C3. (And, of course, it changes the contents of files that are in both commits, to whatever goes with C3.) The files from C3 are now, by definition, tracked.

Note: commits are uniquely identified by their hash IDs. A repository either has the complete commit, or has nothing of that commit. When you connect two repositories, Git's general process is to yank into itself all commits that the sending repository has, that the receiving repository lacks.2 That's whole commits, not files. You then git checkout one of those commits to populate your index and your work-tree. Branch names like master and develop mainly serve to identify one particular commit, namely the commit that Git is to use as the tip of that branch.

You can get what you want by playing fancy tricks with multiple index files. But you'll need separate (unconnected) repositories with a single shared work-tree, which is tricky, and you'll need to commit everything separately to the two separate repositories, which is also tricky. You also won't be able to use .gitignore files usefully (you'll need to use the per-repo $GIT_DIR/info/exclude instead). I don't recommend attempting this: I don't think I'd want to try to do it myself, and I know most of the dark corners of Git. :-)


1This index thing actually has three names, reflecting its three purposes: it (1) indexes the work-tree; (2) acts as a staging area in which you build up the next commit you will make; and (3) works as a cache to make git commit go very fast.

2This is an deliberate overstatement—the truth has to do with graph theory and reachability—but it's good enough for an initial view.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Thanks. Can I have two repositories with different work-tree. I can commit them separately. How can I do this? – rostamiani Aug 03 '18 at 12:18
  • Two different repositories with two different work-trees is fine: that's what Git does "out of the box". Just create the two repositories in two separate file system locations and work with them. – torek Aug 03 '18 at 15:00
  • OK. But Can I do this with nesting folders? – rostamiani Aug 03 '18 at 16:31
  • Sure: `dir` can have `dir/.git` and also `dir/sub` where `dir/sub` has `dir/sub/.git`. You will probably want to have `dir/.gitignore` say to ignore `dir/sub`. – torek Aug 03 '18 at 17:18
  • NO, I want dir/.git repository to include all dir including dir/sub files and dir/sub/.git to include just dir/sub – rostamiani Aug 03 '18 at 17:31
  • Ah: you *can* do that, but I've never found anyone who likes the result. – torek Aug 03 '18 at 18:35
  • I like to, but how? I tried but parent repository does not add files inside child repository. Which command should I use? – rostamiani Aug 03 '18 at 23:29
  • Your Git is probably seeing the `.git` in the subdirectory and thinking: *I'd best not add these, if anything this should be a submodule.* I remember Git used to behave that way at one time. I thought modern Git did not behave that way any more. Which Git version are you using? – torek Aug 03 '18 at 23:36
  • git version 2.18.0.windows.1 And I cannot add files in child repository. I added the error in the question – rostamiani Aug 04 '18 at 05:13