On Wed, Oct 19, 2016 at 6:27 AM, Robert Dailey <rcdailey.lists@xxxxxxxxx> wrote: > On Tue, Oct 18, 2016 at 4:17 PM, Stefan Beller <sbeller@xxxxxxxxxx> wrote: >> On Tue, Oct 18, 2016 at 12:35 PM, Robert Dailey >> <rcdailey.lists@xxxxxxxxx> wrote: >>> Hello git experts, >>> >>> I have in the past attempted to integrate submodules into my primary >>> repository using the same directory name. However, this has always >>> caused headache when going to and from branches that take you between >>> when this integration occurred and when it didn't. It's a bit hard to >>> explain. Basically, if I have a submodule "foo", and I delete that >>> submodule and physically add its files under the same directory "foo", >>> when I do a pull to get this change from another clone, it fails >>> saying: >>> >>> error: The following untracked working tree files would be overwritten >>> by checkout: >>> foo/somefile.txt >>> Please move or remove them before you switch branches. >>> Aborting >>> could not detach HEAD >>> >>> >>> Obviously, git can't delete the submodule because the files have also >>> been added directly. I don't think it is built to handle this >>> scenario. Here is the series of commands I ran to "integrate" the >>> submodule (replace the submodule with a directory containing the exact >>> contents of the submodule itself): >>> >>> #!/usr/bin/env bash >>> mv "$1" "${1}_" >>> git submodule deinit "$1" >> >> This removes the submodule entries from .git/config >> (and it would remove the contents of that submodule, but they are moved) >> >>> git rm "$1" >> >> Removing the git link here. >> >> So we still have the entries in the .gitmodules file there. >> Maybe add: >> >> name=$(git submodule-helper name $1) >> git config -f .gitmodules --unset submodule.$name.* >> git add .gitmodules >> >> ? (Could be optional) > > Actually I verified that it seems `git rm` is specialized for > submodules somewhere, because when I run that command on a submodule > the relevant entries in the .gitmodules file are removed. I did not > have to do this as a separate step. > >>> mv "${1}_" "$1" >>> git add "$1/**" >> >> Moving back into place and adding all files in there. >> >>> >>> The above script is named git-integrate-submodule, I run it like so: >>> >>> $ git integrate-submodule foo >>> >>> Then I do: >>> >>> $ git commit -m 'Integrated foo submodule' >>> >>> Is there any way to make this work nicely? >> >> I think you can just remove the gitlink from the index and not from the working >> tree ("git rm --cached $1") > > What is the goal of doing it this way? What does this simplify? You don't have to mv it back and forth with an underscore I would imagine? > >>> The only solution I've >>> found is to obviously rename the directory before adding the physical >>> files, for example name it foo1. Because they're different, they never >>> "clash". >> >> Also look at the difference between plumbing and porcelain commands[1], >> as plumbing is more stable than the porcelain, so it will be easier to maintain >> this script. > > Which plumbing commands did you have in mind? None specifically. I write scripts using porcelain all the time for personal use. But if you were planning to publish this seriously then I'd recommend looking at plumbing commands. > >> I think this would be an actually reasonable feature, which Git itself >> could support via "git submodule [de]integrate", but then we'd also want >> to see the reverse, i.e. take a sub directory and make it a submodule. > > Integrating this as a feature might be fine, I think when you bring up > the question of retaining history makes things much harder. > Fortunately for me that is not a requirement in this case, so I'm able > to do things with much less effort. That reminds me of subtree merging, which could be used for this case. (see 'git subtree') > > However the primary purpose of my post was to find out how to > integrate the submodule without the error on next pull by other > collaborators of my repository. It's a real pain to recover your > working copy when going inbetween commits where the submodule > integration happened inbetween them. I did quote the exact error > message I got in my original post. You could try this patch series: https://github.com/jlehmann/git-submod-enhancements/tree/git-checkout-recurse-submodules (rebased to a newer version; no functional changes:) https://github.com/stefanbeller/git/tree/submodule-co (I'll rebase that later to origin/master) > > Do you have any info on how I can prevent that error? Ideally I want > the integration to go smoothly and transparently, not just for the > person doing the actual transition (me) but for everyone else that > gets those changes from upstream. They should not even notice that it > happened (i.e. no failed commands, awkward behavior, or manual steps). It depends on how long you want to postpone the transition, but I plan to upstream the series referenced above in the near future, which would enable your situation to Just Work (tm). ;)