On Wed, 13 Mar 2024, Paul M Foster wrote:
Folks: I have a /home/paulf/stow directory with contains subdirectories for each of the packages whose dotfiles I want to manage, like: /home/paulf/stow/alacritty In each subdirectory, I have all the config files for that packages, under git management. This means that the directory will look like this: /home/paulf/stow/alacritty/.git /home/paulf/stow/alacritty/.config/alacritty/alacritty.yml This works well with stow (configs are now symlinks in $HOME). I'd like to copy all of this to a git repo on gitlab. You would think you could go to the ~/stow directory, "git init", then "git add" each directory, and all is good. However, git looks inside the directories and sees there are already .git directories there, and refuses to add the directories and their contents to its repo. Instead, it wants you to use "submodules", to wit: git submodule add ./alacritty This adds an *empty* alacritty subdirectory to the git repo, which isn't useful. I need a way to bring all these subdirectories and their contents under a git repo so I can send it to gitlab. Any suggestions? Paul
So I thought this was a rather interesting exercise and tried it on one of my repos that contains etckeeper files, one branch per machine. I came up with this script (beware if your branches have weird characters in the names or something, there's limited quoting/escaping here.) # clone the repo (I'm assuming you've managed to merge all your repos # into one with a separate branch for each. I started from this so I've # not got commands to do it but it shouldn't be hard, just add a # commonremote and push to a named branch for each existing repo) git clone -n git@einstein:/configs.git cd configs # Create a new branch with a completely empty commit at the root # This must not match any existing branch. rbp=rebasepoint tree=$( git hash-object -wt tree --stdin < /dev/null ) commit=$( git commit-tree -m 'root commit' $tree ) git branch $rbp $commit git checkout $rbp # Don't know how to stop this one getting created but we need to delete # it to simplify the rest. I expected git clone -n to not create this! git branch -d master # First map all the commits in each branch on the remote into a # subdirectory of the branch name on my (relatively low power) machine # this maps about 30 objects per second. # This has a very long line with subtle quoting - take care when # cutting/pasting. for i in $( git branch -r | grep -v HEAD ); do echo $i git filter-branch -f --index-filter 'git ls-files -s | sed "s:\t\"*:&'"$i"'/:" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && if [ -e "$GIT_INDEX_FILE.new" ]; then mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; fi' -- $i done # Now rebase each branch onto the previous one (Note that we're starting # with rebasepoint that we created above) # This gets progressively slower on my machine, not exactly sure why. for i in $( git branch -r | grep -v HEAD ); do git branch --track ${i#origin/} $i git rebase $rbp ${i#origin/} rbp=${i#origin/} done # The branch you are on at this point should be a branch that combines # all of the upstream branches # If anything goes wrong, just delete the configs directory and start # again. You are changing nothing on the upstream unless/until you # decide to push. tim@dirac:~/git/flatten/configs (xen3)$ ls origin/ aptmirror17 citrix17 dirac ipmi17 ntp17 wiki17 aptmirror19 cups17 einstein ipmi19 ntp19 wiki19 asterisk17 debootstrap17 firewall17 ipmi2 proxy17 xen17 asterisk19 debootstrap19 firewall19 mail17 proxy19 xen19 backup17 debootstrap2 firewall2 mail19 rpi xen2 bind17 dhcp17 imap17 master rpi-flat17a xen3 bind19 dhcp19 imap19 mtd19 victoria17 HTH. Tim.