3

For example, given the worktree below, if I init git repo in folder my_folder and type git add ., I do not want the folders django-backend and test-vue added or tracked by Git.

my_folder/
  audio/
    Michael Jackson.mp3
  images/
    nature.jpg
  projects/
    projects_info.md
    django-backend/
      .git/
      manage.py
      poetry.lock
    test-vue/
      .git/
      yarn.lock

I tried this but didn't get the desired effect:

.git/**/*
TylerH
  • 20,799
  • 66
  • 75
  • 101
bumloner
  • 33
  • 4
  • 5
    I don't think this is possible. Ignore the specific folders you want to ignore – mousetail Dec 16 '22 at 09:22
  • What does `git status` tell about the directories that you want to be ignored? – j6t Dec 16 '22 at 10:27
  • 1
    I would agree with @sharpgeek [that git submodule](https://stackoverflow.com/a/74823159/8910547) is maybe the way to go if you want versions of the parent project to be tied to specific versions of the "child" projects. Or a git [subtree](https://stackoverflow.com/questions/31769820/differences-between-git-submodule-and-subtree). Also should read about best practices for ["monorepos"](https://en.wikipedia.org/wiki/Monorepo). Finally, consider [whether a package manager is the better approach for your case](https://stackoverflow.com/questions/52256490/package-manager-vs-git-submodule-subtree). – Inigo Dec 16 '22 at 12:31
  • 1
    +1 for Michael Jackson.mp3 - and hint: if you read the manual about .gitignore, you'd have found that explained. And you don't need to ignore `.git` subfolders, the whole subrepro is automatically ignored by git. – hakre Dec 16 '22 at 15:09
  • 1
    It's really not need any extra instructions in .gitignore to skip tracking workdirs in subfolders. Thank you @hakre. Problem solved. – bumloner Dec 16 '22 at 18:38

3 Answers3

2

Consider using Git submodules for when using multiple repositories within the super project.

Submodules are a bit trickier to use in the beginning in comparison with a single repository, however it pays off as they will allow you to have fine grained control over each individual repository's history (.git).

In the example of your question, the django-backend and test-vue repositories could be submodules added to the my_folder's repo.

git init
git submodule add [remote to django-backend] django-backend
git submodule add [remote to test-vue] test-vue
git submodule init
git submodule update

Adding submodules to the super project will create file named .gitmodules.

Each submodule will have its own history. For example, each submodule's latest commit can be obtained like this:

cd submodule-dir
git pull
cd ..

And then commit your work, with the submodule sync'ed:

git commit -am "Synchronized with submodules"

Later on, when cloning the super project repository, it is necessary to use git clone --recurse-submodules [url/to/super/project] to bring it back with all its submodules.

In general, that's it. There are many good answers on Stack Overflow that details the manageability aspects of using git repository containing submodules.

sharpgeek
  • 481
  • 2
  • 14
  • 1
    I agree (and upvoted) this may be the way to go. See my comment under the question for more thoughts. – Inigo Dec 16 '22 at 12:35
  • The goal is not to control nested projects, but to ignore them workdirs altogether. But thanks for the idea. – bumloner Dec 16 '22 at 13:00
  • Are there no dependencies between versions of `my_folder/`, `django-backend/` and `test-vue/`? – Inigo Dec 16 '22 at 15:08
1

If you only wanted to ignore any .git folder anywhere in the worktree, it would be easy:

**/.git/

But it looks like you want to ignore the parent folder of any .git folder anywhere in the worktree. There is no single line you can add to .gitignore that will do this for you. You either have to manually do it, e.g.

my_folder/projects/django-backend/

or create a Git pre-commit hook that calls a script that detects new folders that should be ignored and adds them to .gitignore and adds the .gitignore change to the commit. This apparently only work for some versions of git. If you have any trouble see the other answer and comments for that SO question.

If it turns out your version of git's pre-commit hook does not include the git add in the commit, you can instead simply have the script abort the commit with a warning message. Since the directory will have been added to .gitignore by the script, you can just commit a second time and it will work.

Here are some SO answers that you can use for more guidance with pre-commit hooks:

Inigo
  • 12,186
  • 5
  • 41
  • 70
  • Yes, I want to ignore the parent folder of any .git folder. Thanks for the comprehensive answer. – bumloner Dec 16 '22 at 12:23
  • For now, I'll stick with `git add` manually, based on the `git status` info. – bumloner Dec 16 '22 at 12:25
  • while `.git/` would already suffice, in case of a subproject it is not even necessary (and git would ignore it - the entry suggested here to add into the .gitignore - anyway). I've added this as an answer to clarify https://stackoverflow.com/a/74829187/367456 @bumloner – hakre Dec 16 '22 at 19:57
-1

Git has you covered, there is no need to .gitignore subrepositories (git repositories inside git repositories).

Once initialized, each has their own history and the superproject only has the entry (compare gitlink).

You can turn it into a git submodule, also anytime later, but there is no requirement to do so at all (git will remind you once you add the gitlink if a submodule is not more in your interest thought).

hakre
  • 193,403
  • 52
  • 435
  • 836
  • Can you point to documentation that states this? – Inigo Dec 16 '22 at 20:00
  • Sure, one part of the documentation that talks about it is the manpage of `git-clean(1)`. – hakre Dec 16 '22 at 20:01
  • @Inigo: Just seeing you wrote the answer promoting submodules, they work similar, compare with the second FORMS in https://git-scm.com/docs/gitsubmodules#_forms and without entry in the git-modules file. – hakre Dec 16 '22 at 20:14
  • I don't see anything in git-clean to back your claim. In fact, [this answer](https://unix.stackexchange.com/a/323490/416743) contradicts you. Please update your answer with an excerpt from official documentation backing you up along with a link (all of the man pages are available on an official place on the web somewhere). Finally, to meet the question's requirements, it has to exclude the not only the nested `.git` directory, but the entire nested repo (i.e. the parent folder). – Inigo Dec 16 '22 at 20:18
  • @Inigo: Trust the terrain not the map: If subprojects won't work, submodules wouldn't work either. And git-clean mentions that it does not clean subprojects unless you particularly double force their deletion. Look again, it's written in there. Same in the submodule docs, but you have to read it yourself, I can only point you to it (paragraphs in the second bullet under FORMS). – hakre Dec 16 '22 at 20:20
  • And what is described in what you linked is not contradicting, but how .gitignore works: once you've put the subtree under version control, you can't ignore that part any longer. you can do this even to a certain stretch over the history of paths in the superproject that are later shared with a subproject. – hakre Dec 16 '22 at 20:26
  • I'll trust an actual test using 2.38.1. I created a repo. Committed a file to it. Then I created a subdirectory, initialized it as a git repo, and committed a file to it (the repo in the subdir). Then I `cd`d back out to the parent repo, and now the subdir shows up as an untracked change with `git status`. To make it go away, I either have to add the name to `.gitignore`, or `git add` it to the parent. That gives me a warning message which confirms your point that it doesn't add the contents, but also suggests I either use git submodule or reverse my `git add`. So not convinced this is kosher. – Inigo Dec 16 '22 at 20:34
  • Yes, exactly that behaviour. It didn't change much over the decades. So it works, whether its kosher you've to decide your own. The warning is so that you don't loose track to which repository the revision is you commit (submodules store the repository, the file-system as well, but that might not suffice for sharing, hence the warning). – hakre Dec 16 '22 at 20:40
  • Ok, so it's submodules on the cheap (with unknown repercussions, but I'm willing to learn). But the question explicity states "I do not want the folders django-backend and test-vue added or tracked by Git.". You solution causes the to be tracked, albeit at the repo commit level, not individual file level. – Inigo Dec 16 '22 at 20:43
  • Are you willing to write an SO question and answer about `Git Submodules *Light*`? – Inigo Dec 16 '22 at 20:44