Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git treat nested git repos as regular file/folders

Tags:

git

I have a top level git repo organized like so:

  • .git/
  • repoA/
    • .git/
    • file
    • file2
    • folder/
    • ...
  • file
  • file2
  • folder/
  • ...

How can I get git to add and commit repoA (and repoA/.git) as if they were regular files/folders?

Specifically, I want to bypass the treatment of such a folder as a submodule but I want to retain the branches/history of the nested repo (so the .git folder is required).

I do not want to alter the state of the nested repo (by committing or merging histories) and do not want to push it to a separate repo on the remote.

The intended result is the same as if I were to tar repoA and un-tar it later. That is, all the files are intact with no modification or special treatment by git.

like image 373
arcyqwerty Avatar asked Oct 29 '15 05:10

arcyqwerty


2 Answers

You can look into git subtree.

For that, if you currently have submodules, you can follow "Convert a git repository from submodules to subtrees":

cat .gitmodules |while read i
do
  if [[ $i == \[submodule* ]]; then
    mpath=$(echo $i | cut -d\" -f2)
    read i; read i;
    murl=$(echo $i|cut -d\  -f3)
    mcommit=`eval "git submodule status ${mpath} |cut -d\  -f2"`
    mname=$(basename $mpath)
    echo -e "$name\t$mpath\t$murl\t$mcommit"
    git submodule deinit $mpath
    git rm -r --cached $mpath
    rm -rf $mpath
    git remote add $mname $murl
    git fetch $mname
    git branch _$mname $mcommit
    git read-tree --prefix=$mpath/ -u _$mname
fi
done
git rm .gitmodules

(test it on a copy of your repo first)

See also "When to use git subtree?", which differs from ingydotnet/git-subrepo.

like image 80
VonC Avatar answered Nov 20 '22 09:11

VonC


This is not directly possible. The .git directory has a special meaning for git. When you run git operations from inside a git work-tree (not necessarily from the top level) without explicitly specifying the path to the repository (via the --git-dir option or the GIT_DIR environment variable) the latter is automatically discovered by looking for the first ancestor directory that contains a .git subdirectory. A .git directory that is intended to be considered as regular content would interfere with that procedure.

However, I can suggest the following workaround:

  1. In your sub-repository, rename the .git directory to something else (e.g. .git.subrepo, .pseudogit, etc):
mv repoA/.git repoA/.pseudogit
  1. Add and commit the sub-repository directory:
git add repoA
git commit -m "Added repoA as regular sub-directory"

After this git operations from inside the sub-repository tree will work using the master repository by default. When you need to study the history of the sub-repository you will have to use the --git-dir option:

cd repoA
git --git-dir .pseudogit log
like image 33
Leon Avatar answered Nov 20 '22 07:11

Leon