On Thu, Jan 09, 2020 at 03:11:50AM -0500, Jeff King wrote: > On Wed, Jan 08, 2020 at 03:19:00PM -0800, Emily Shaffer wrote: > > > Subject: clone: teach --single-branch and --branch during --recurse > > A minor nit, but this subject confused me for a moment. I think we'd > usually say "teach" for a new feature being implemented, and this is > really just about passing along the existing features. Something like: > > clone: pass --single-branch and --branch when recursing submodules > > would have been a bit more obvious (to me anyway). > > > Previously, performing "git clone --recurse-submodules --single-branch" > > resulted in submodules cloning all branches even though the superproject > > cloned only one branch. Pipe --single-branch and its friend, --branch, > > through the submodule helper framework to make it to 'clone' later on. > > Since I don't really use submodules, I don't have much data or even > intuition to go on. But could this be a regression for some situations? > E.g., imagine I have a repo "parent" whose branch "foo" has a submodule > "child", but "child" only has a branch "bar". What happens now if I "git > clone --recurse-submodules --single-branch -b foo parent", and what will > happen after this patch? > > I think it works before, but doesn't now. > > Setting up like this: > > git init child > ( > cd child > git checkout -b bar > echo whatever >file > git add file > git commit -m 'child commit' > ) > > git init parent > cd parent > git checkout -b foo > git submodule add $PWD/../child > git commit -m 'add submodule' > > if I use the current tip of master, I get: > > $ git clone --recurse-submodules --single-branch -b foo parent cur > Cloning into 'cur'... > done. > Submodule 'child' (/home/peff/tmp/parent/../child) registered for path 'child' > Cloning into '/home/peff/tmp/cur/child'... > done. > Submodule path 'child': checked out 'b5cbfcc9fec3b7d67e305468624fed2ba1aa4758' > > $ git -C cur/child log -1 --oneline | cat > b5cbfcc child commit > > with your patch, I get: > > $ git.compile clone --recurse-submodules --single-branch -b foo parent new > Cloning into 'new'... > done. > Submodule 'child' (/home/peff/tmp/parent/../child) registered for path 'child' > Cloning into '/home/peff/tmp/new/child'... > warning: Could not find remote branch foo to clone. > fatal: Remote branch foo not found in upstream origin > fatal: clone of '/home/peff/tmp/parent/../child' into submodule path '/home/peff/tmp/new/child' failed > Failed to clone 'child'. Retry scheduled > Cloning into '/home/peff/tmp/new/child'... > warning: Could not find remote branch foo to clone. > fatal: Remote branch foo not found in upstream origin > fatal: clone of '/home/peff/tmp/parent/../child' into submodule path '/home/peff/tmp/new/child' failed > Failed to clone 'child' a second time, aborting > > $ git -C new/child log -1 --oneline | cat > 11acb3a add submodule > > (there's nothing checked out in the submodule). > > I have no idea how common this kind of thing would be, and I expect in > most cases your patch would do what people want. But we might need to be > better about retrying without those options when the first clone fails. Yeah, that's interesting. A retry sounds like a pretty solid approach, although if someone's being cautious and using --single-branch I wonder if that's really something they want (since that's avoiding grabbing extraneous branches). I suppose at the very least, --single-branch without --branch should become recursive. Whether --branch should become recursive, I'm not totally sure. The two scenarios I see in conflict are this: - Superproject branch "foo" - submodule A branch "foo" - submodule B branch "foo" and - Superproject branch "foo" - submodule A branch "bar" - submodule B branch "baz" If we propagate --branch, the first scenario Just Works, and the second scenario requires something like: git clone --recurse-submodules=no --single-branch --branch foo https://superproject git submodule update --init --single-branch --branch bar A/ git submodule update --init --single-branch --branch baz B/ (I guess if the superproject knows what branch it wants for all the submodules, you could also just do "git submodule update --init --single-branch" and have it go and ask for all of them.) If we don't propagate --branch, the second scenario Just Works, and the first scenario requires something like: git clone --recurse-submodules=no --single-branch --branch foo https://superproject git submodule update --init --single-branch --branch foo (That is, I think as long as 'update' takes --branch, even if it's not passed along by 'clone', it should still work OK when delegating to everyone.) Let me know if I misunderstood what you were worried about. I don't use submodules heavily for myself either. I'll try and ask around a little to see what folks want, at least here. The ergonomics seem pretty similar, so I guess it comes down to having explicit documentation. > > -Peff