Reputation: 15453
I have no idea what happened that Git started telling me that I added another git repository inside my current repository. I don't remember doing that, I have been working on writing code and configuration files all day.
So it gave me this warning: adding embedded git repository: client
I tried doing git rm --cached client -f
, Git didn't care, warning still there.
so I did a git add .
When I pushed the project, I could not open up the client/
folder as a link on the Github repository.
I deleted the Github repository.
I am back to changes not staged for commit: modified: client (modified content, untracked content)
, it does not let me do git checkout -- client/
either.
I essentially want to ensure that when I create a repo for this project and push all these folder that I am able to click on the folders and view the files inside of them.
This is my Dockerfile.dev
inside of client/
:
FROM node:alpine
WORKDIR '/app'
COPY ./package.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "start"]
This is my Dockerfile
for production purposes inside of client/
:
FROM node:alpine
WORKDIR '/app'
COPY ./package.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx
EXPOSE 3000
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/build /usr/share/nginx/html
I don't believe any of the configuration above could have create a .git
folder inside of client/
.
I looked through my command line history and I do not see where I ran a git init
on the client/
directory.
At this point how do I clean this up? git rm --cached client
did not seem to work and neither did git clean -f -d
.
Upvotes: 1
Views: 487
Reputation: 489508
I am back to
changes not staged for commit: modified: client (modified content, untracked content)
This indicates that your existing Git repository is treating the path-name client
as a submodule. A submodule is nothing more or less than a particular form of reference to some other Git repository.
This whole picture can get confusing very quickly, since every local (e.g., on-your-laptop) Git repository usually contains a reference to another Git repository already: the one that's on your hosting provider, such as GitHub. That is, if we draw a relationship, we get something like this:
+-----------------+ +-----------------+
| your Git repo | --origin-> | GitHub repo |
|=================| |=================|
| commits | | commits |
| (shared w/ | <=========> | |
| origin) | | |
|-----------------| | |
| branch names | (private) | |
|-----------------| |-----------------|
| remote-tracking | | branch names |
| names: origin/* | <------------- | |
+-----------------+ +-----------------+
There are two repositories, one on your laptop (your Git repo) and one on GitHub or Bitbucket or GitLab or whatever. Yours calls theirs origin
. You and they share commits by copying back and forth: you run git fetch
to get new commits from them, and you run git push
to send new commits to them. They have branch names like master
and develop
and so on, and you have branch names, but you also have remote-tracking names like origin/master
. Your Git simply copies their branch names to your repo, while adding origin/
—the name you are using to hold the URL for the GitHub repo—in front.
Each of the commits in these two repositories, like any commit, has a unique hash ID. If you and they have the same hash ID for some commit, you have the same commit. So when your Git talks with their Git, it can just ask: do you have hash ID a123456...
? or tell it: here's commit a123456...
and provide the full contents of that commit.
So far so good, but now you've thrown a submodule into the mix.
In a submodule, each of your commits holds the raw hash ID of a commit in some other Git repository. This "other Git repository" is a third Git repo:
+-----------------+
| your Git repo |
|=================|
a123456 > | commits |
| |-----------------|
| | branch names |
| |-----------------|
| | remote-tracking |
| | names: origin/* |
| +-----------------+
|
| +--------------+ +--------------+
+--------> | README.md | | README.md |
| file1 | | file3 |
| dir1/file2 | | file4 |
| client ------|---> b789abc: | ... |
+--------------+ +--------------+
where b789abc...
is actually a commit in this third repo. This third repo of course can also have its own origin
, which would be a fourth repository in the picture. That fourth repository is also presumably on GitHub or Bitbucket or GitLab or whatever.
To work with a submodule properly, your own repository—the one Git calls a superproject, which is the one on the left in this second diagram—must contain a file named .gitmodules
. This file lists the URL of the fourth Git repository, i.e., the one we didn't draw here.
In this case, we've shown a commit in your repository that contains snapshots of files, plus a gitlink. This gitlink says that for the name client
, whoever is working with this repository should clone the submodule repository and tell that Git to git checkout b789abc...
(by its unique hash ID).
The URL you are to store in .gitmodules
enables anyone who clones your GitHub repository to also clone this fourth repository. After that, their local (laptop) clone can use the hash ID—in this case b789abc...
—stored in the gitlink entries of the commits that are shared in your laptop and GitHub superproject repositories, to git checkout
the right hash ID in their local Git repository that they make by cloning this fourth Git repository.
(You might need to read over this section many times. It's complicated!)
If you don't want a submodule at all:
Move the other Git repository completely out of the way:
mv client /some/other/path
(or whatever you use to move everything, including the .git
folder).
Copy all the files, but not the .git
directory/folder, from the place you moved all this stuff to.
(Another way to do this that might be easier: move the .git
directory out of the client/
subdirectory, or remove it entirely.)
Now you have ordinary files—which you did before—but ordinary files that you can git add
in the ordinary way because there's no .git
folder in the client/
folder standing in the way. Your Git repository won't try to control some other Git repository via all this submodule stuff.
Unfortunately, you must do this after getting rid of any submodule that you already created. This is painful. Be very sure you want to do this. If you have existing commits that list client
as a submodule, you'll have to either be very careful whenever you use those existing commits, or do a major history rewrite operation to replace all those commits with new-and-improved ones that don't use client
as a submodule.
See the last section below if you haven't made any commits that refer to this submodule and don't have a .gitmodules
file.
This gets a little bit tricky, but it's really not that bad. Remember: the submodule is a Git repository. It should have a counterpart over on GitHub or whatever, which the submodule calls origin
. The submodule itself has little or no idea that it's living underneath a superproject: it's just a regular old Git repository. The only thing special is that the superproject tends to cd
into the submodule Git and tell it to git checkout
one commit by hash ID, putting it into detached HEAD mode.
So: enter the submodule yourself, and take it out of "detached HEAD" mode, by either creating a new branch name for the current commit, or checking out some existing branch name. If you have changes that you need to save, you can git stash
them or make a commit here first, then return to this commit later. If your changes are really simple—say, updating the README
file slightly—you can just re-create them.
Now, re-create your changes on this branch, or commit them on this branch whose name you just invented, or whatever it takes to commit them on some branch:
... do work ...
git add <files>
git commit
(and supply commit message, etc). You'll see that this makes a new commit, which gets its own new unique big ugly hash ID. You can now git push
or use a pull request to send this new commit, under its new or existing branch name, to the fourth Git repository, the one this submodule Git calls origin
.
(If you have to go through a pull request, this can take a long time, obviously. If you like to live dangerously, you can go ahead and use the new hash ID on the assumption that whoever controls the pull requests will take your commit as is. If not, wait until they take it, or notify users that they might not be able to use the superproject update you're about to make. Remember, your superproject records raw hash IDs. If the people controlling the PRs take your changes slightly differently, the commit they put into the upstream repo will have a different hash ID, and you'll have to update your submodule again.)
Now your new commit in the submodule is available to everyone else too. You're now done updating the submodule, and can go back to the superproject:
cd .. # or whatever to get to the superproject
Running git status
in the superproject will now show that the submodule has a new commit in it. (Running git diff
or git submodule status
will show similar things, although you can configure git diff
to show actual diffs instead of just a raw hash ID. You can configure git status
in complicated ways here too, but the default is to just say (new commits)
.)
Your job is now to record the new hash ID in the gitlink that will be committed in your next commit:
git add client
Now the changes are staged—git status
will show them under changes staged for commit
this time. Now you can git commit
the result as an updated gitlink, along with everything else that goes into each new commit you make. You now have an ordinary commit—just, one that uses a gitlink to refer to a commit in a third Git repo that refers to a fourth Git repo, that your superproject calls a submodule.
.gitmodules
, etc, and have not made any commits with this weird submodule stuff yet?(Note: It sounds like you have already made some commits, because you talked about looking at the commits via the GitHub web browser. So this may not apply at all.)
If you have run:
git add client
and client
has its own .git
, a modern Git will notice and create the first part—but only the first part—of a submodule: a sort of half-baked one. This one is missing the .gitmodules
file that tells future git clone
operations where the fourth Git repository is, so that those folks' Gits can make their own third repositories.
If you haven't committed this yet, though, this gitlink isn't in any commits. That makes cleaning it up easy. Just run:
git rm --cached client
to remove the gitlink entry from your index/staging-area. Then, once you have de-.git
-ified the client
directory (i.e., now if you already did this, in a moment if you haven't yet), you can git add client
and it will add the files in the client
folder (and recursively, any files in any sub-folders) this time.
Upvotes: 1