apenwarr’s git subtree has a --squash
option that might do very nearly what you want.
remote=libfoo
branch=master
prefix=helpers/libfoo
git fetch "$remote" &&
git subtree add --prefix="$prefix" --squash "$remote/$branch"
: Later, once there are changes to pick up.
git subtree pull --prefix="$prefix" --squash "$remote" "$branch"
git subtree records extra information in the commit messages of the commits it generates; this extra information allows it to effectively do merges without having to incorporate the actual history of the subtree being merged.
If you know that you will never make any changes to the subtree in the “super” repository (i.e. all the changes in the subtree will always come from some other repository), then you could do without git subtree and just repeat the git read-tree --prefix=
part of the subtree merge method (though you have to clean out your current subtree from both the index first).
remote=libfoo
branch=master
prefix=helpers/libfoo/
: replace the local subtree with whatever the other repository has
git fetch "$remote" &&
git rm -r --ignore-unmatch "$prefix" &&
git read-tree --prefix="$prefix" "${remote}/${branch}" &&
git checkout -- "$prefix" &&
git commit -m "update $prefix from $remote $branch"