Re: RFC/Discussion - Submodule UX Improvements
From: Jacob Keller <hidden>
Date: 2021-04-22 15:33:06
On Fri, Apr 16, 2021 at 4:38 PM Emily Shaffer [off-list ref] wrote:
-- Create mode (git switch -c / git checkout -b)
1. The current worktree is checked for uncommitted changes to tracked files. The
current worktree of each submodule is also checked.
2. A new branch is created on the superproject; that branch's ref is pointed to
the current HEAD.
3. The new branch is checked out on the superproject.
4. A new branch with the same name is created on each submodule.
a. If there is a naming conflict, we could prompt the user to resolve it, or
we could just check out the branch by that name and print a warning to the
user with advice on how to solve it (cd submodule && git switch -c
different-branch-name HEAD@{1}). Maybe we could skip the warning/advice if
the tree is identical to the tree we would have used as the start point
(that is, the user switched branches in the submodule, then said "oh crap"
and went back and switched branches in the superproject).
b. Tracking info is set appropriately on each new branch to the upstream of
the branch referenced by the parent of the new superproject commit, OR to
the default branch's upstream.
5. The new branch is checked out on each of the submodules.
What doesn't already work:
* Safety check when leaving uncommitted submodule changes
* Propagating branch names to submodules currently requires a custom hacky
repolike patch
* Error handling + graceful non-error handling if the branch already exists
* "Knowing what branch to push to": copying over which-branch-is-upstream info
** Needs some UX help, push.default is a mess
* Tracking info setupsAs someone who uses submodules extensively for various projects, I'm not sure about propagating branches into the submodules. I think i'd only want this behavior if/when I intend to work on a submodule. Because of the nature of submodules being distinct, we tend towards doing submodule work separately, merging it, and then pulling that change into the super project.
-- Switching to an existing branch (git switch / git checkout) 1. The current worktree is checked for uncommitted changes to tracked files. The current worktree of each submodule is also checked. 2. The requested branch is checked out on the superproject. 3. The submodule commit or branch referenced by the newly-checked-out superproject commit is checked out on each submodule. What doesn't already work: * Same as in create mode
I'd imagine there are multiple cases here. For cases where you're not actively developing submodule, you want to just checkout the right contents (i.e. what is tracked by the super project). But if you're developing the submodule in conjunction with the super project you might want to instead checkout the matching work (as in above where you create a branch within the submodule?)
- git status
-- From superproject
The superproject is clean if:
* No tracked files in the superproject have been modified and not committed
* No tracked files in any submodules have been modified and not committed
* No commits in any submodules differ from the commits referenced by the tip
commit of the superproject
Advices should describe:
* How to commit or drop changes to files in the superproject
* How to commit or drop changes to files in the submodules
* How to commit changes to submodule references
* Which commit/branch to switch the submodule back to if the current work
should be dropped: "Submodule "foo" no longer points to "main", 'git -C foo
switch main' to discard changes"
What doesn't already work:
* "git status" being super fast and actually possible to use.
** (That is, we've seen it move very slowly on projects with many
submodules.)
* Advice updates to use the appropriate submodule-y commands.Yea, a slow status means people tend to not use it!
-- From submodule git status's behavior for submodules does not change compared to single-repository Git, except that a red warning line will also display if the superproject commit does not point to the HEAD of the submodule. (This could look similar to the detached-HEAD warning and tracking branch lines in git status today, e.g. "HEAD is ahead of parent project by 2 commits".) What doesn't already work: * "git status" from a submodule being aware of the superproject.
This seems like a very good improvement. One of the biggest complaints about submodules I've had to deal with when helping coworkers is the fact that submodules weren't moved forward automatically, and that they had no real idea that the submodule was different. This tended to lead towards commits including submodule rewinds on accident.
- Worktrees
When a user runs 'git worktree add' from the superproject, each submodule in the
new worktree should also be created as a worktree of the corresponding submodule
in the original project.
What doesn't already work:
* worktrees and submodules getting along - submodules are now freshly cloned
when creating a superproject worktreeThis is something I would love to see fixed! Right now using work trees on a project with submodules is problematic. Especially a project with many submodules, as this ends up making many extra clones, taking disk space and network time to setup.
- git clone --reference [--dissociate] When cloning with an alternate directory, submodules should also try to use object stores associated with the referenced project instead of cloning from their remotes right away. It is unclear how much of this works today. What doesn't already work: * Writing some tests and making them pass