Home > OS >  How can I add files from different repository?
How can I add files from different repository?

Time:11-30

I have the following setup:

mkdir /base; cd /base

git init a
touch a/file.txt

git init b
cd b
git config core.worktree=/base
git add ../a/file.txt

I have a /base folder, which contains two repositories (a and b). Repo a contains just a file (not even commited). Repo b set the worktree to /base (where both repos resides). When I try to add the file.txt from repo a, it did not work (it just is not staged).

When I remove the .git folder from a, I can add the file.

rm -rf ../a/.git
git add -vvv ../a/file.txt 

I am not exactly sure why this is the case. Maybe git prevent adding the file because it thinks it is a submodule? I've tried to prevent this with some submodule settings, but with no effect.

git config submodule.ignore all
git config submodule.active false

How can I trick git to forcefully add the file? (-f is just for ignored files and -v gives no information).

CodePudding user response:

You can't.

More precisely, the path name of a file in some commit must consist only of "descending" components, all of which reside in this repository, not in any other repository on the file system. So if a file's path name is ../dir/file, you can't add it, and a if a file's name is dir/sub/file where dir/sub contains a .git, you can't add it.

That last restriction is the submodule restriction:

Maybe git prevent adding the file because it thinks it is a submodule?

It is a submodule, if it's in another directory with a .git in it.

You can bypass the submodule restriction using git update-index, but if you do, you're straying into dangerous territory:

$ git hash-object -w dir/sub/foo
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
$ git update-index --add --cacheinfo 100644,e69de29bb2d1d6434b8b29ae775ad8c2e48c5391,dir/sub/foo

What happens at this point isn't well defined if dir/sub really is a Git repository. (I made a temporary pair of repositories to run these commands, and did not check any further here.) Note that ../ is not valid as a path component:

$ git update-index --add --cacheinfo 100644,e69de29bb2d1d6434b8b29ae775ad8c2e48c5391,../sub/foo
error: Invalid path '../sub/foo'
fatal: git update-index: --cacheinfo cannot add ../sub/foo

CodePudding user response:

Please read the important note at the bottom for a better alternative solution!

The literal answer to the question asked

Although you can't, as torek explained very well, there is a workaround.

You can version your file in b and copy it in a with a script. Here is your setup:

/base
|- a
|  |- .gitignore
|- b
   |- copy-file
   |- resources
      |- file.txt
  • /base/b/resources/file.txt is your file that should belong to /base/a but versionned in /base/b.
  • /base/b/copy-file is a script that copies the file to the correct location, don't forget to make it executable.
  • /base/a/.gitignore ignores file.txt so that the copied file isn't versionned in /base/a.

Your workflow is the following:

  1. Update all your branches.
  2. Run /base/b/copy-file (possibly with git hooks), that will place an unversioned copy of your file.txt in /base/a.
  3. Start working.

Important note

I know it seems tempting to do it this way, because of reasons that pushed you into that current workflow of yours, but even if I answered your question as is, I also suggest you look into different approaches. For example:

  • Keep the copy-file script in /base. There is probably a reason why you haven't done a single project with both those subfolders. That reason must be reusability. If you define the relative path of your a subdirectory in your b repository, that means they are somehow connected and interdependant. Which brings me to the next and better solution:
  • Use a package manager! I'm sure your language has one of those fancy package managers, they're everywhere! So use npm, pip, composer or whatever your language works with, make your b sub-project require your a sub-project (or the other way around, it's not really clear what requires what in your question) and use namespaces to reference the distant file, when you need it in the other sub-project. You don't usually need to publish one of your sub-projects to use the official package manager website, you should have a way to include a Git repository.
  •  Tags:  
  • git
  • Related