Git development
 help / color / mirror / Atom feed
From: Glen Choo <chooglen@google.com>
To: git@vger.kernel.org
Cc: Glen Choo <chooglen@google.com>,
	rsbecker@nexbridge.com,
	Philippe Blain <levraiphilippeblain@gmail.com>,
	Emily Shaffer <emilyshaffer@google.com>
Subject: [PATCH 0/1] checkout: teach "git checkout" to checkout submodule branches
Date: Wed,  9 Feb 2022 14:52:35 +0800	[thread overview]
Message-ID: <20220209065236.36494-1-chooglen@google.com> (raw)

This series is based on gc/branch-recurse-submodules.

Since gc/branch-recurse-submodules is queued for next, I was hoping to
get some feedback on a followup feature - teaching "git checkout
--recurse-submodules" to checkout the branches created by "git branch
--recurse-submodules".

When "git branch --recurse-submodules" was introduced [1], we noted that
existing Git commands ignore submodule branches and that we would teach
them to respect submodule branches if submodule.propagateBranches=true.

This series teaches "git checkout" to understand
submodule.propagateBranches=true so that "git checkout" checks out the
branches created by "git branch --recurse-submodules". Specifically,
the behavior of "git checkout" follows the proposal laid out in the
submodule branching RFC [2] (an abridged description can also be found
in the commit message).

This series isn't ready for full review yet (see "Future work"), but the
approach is unusual enough that I thought it would be useful to get
early feedback and evaluate alternatives (instead of polishing a
potentially bad approach).

I'd appreciate any feedback, though I'd like for reviewers to focus on
fleshing out the design space. This could include answering the
questions in "Questions", or providing additional context to "git
checkout" that I missed.

(Cc-ed some people who have shown some interest in submodules in the
past)

= Approach

Presently, "git checkout" updates the superproject/submodule HEAD and
trees using different machinery:

- unpack-trees updates the superproject tree, submodule tree and
  submodule HEAD
- cmd_checkout() porcelain (specifically, update_refs_for_switch()),
  updates the superproject HEAD

This works well if we assume that "git checkout" always leaves
submodule's HEAD pointing to a commit id, but this is no longer true
with submodule.propagateBranches=true, so this series updates submodules
differently:

- disable submodule updating in unpack-trees, so that neither the
  submodule HEAD nor submodule tree are updated
- update the submodules' HEAD and tree using a "git checkout" subprocess
  in the cmd_checkout() porcelain (specifically,
  update_refs_for_switch())

Doing work in the cmd_checkout() porcelain lets us support complicated,
"git checkout" workflows that don't make sense in unpack-trees:

- updating the submodule's tree using the submodule's "topic" branch
  instead of the gitlink of the superproject's "topic" branch
- updating the submodule's HEAD to a ref instead of a commit id
- checking out the gitlink when the submodule's HEAD points to a branch
  pointing to the same commit (unpack-trees will ignore the submodule if
  it notices that the HEAD's oid does not change)
- preventing a checkout if a submodule is in detached HEAD and not
  pointing to the superproject gitlink (Future work, see RFC for more
  details [2])

The tradeoffs are:

- we lose atomicity guarantees because we run multiple subprocesses
  instead of a single unpack_trees()
- overhead of spawning child processes
- blurring of the lines between cmd_checkout() porcelain and
  unpack-trees - superproject trees and HEAD are still updated
  in different code locations (by cmd_checkout() porcelain and
  unpack-trees respectively), but submodule trees and HEAD are both
  updated by a single "git checkout" subprocess.

= Questions

- Is this an accurate summary of benefits and tradeoffs? Am I missing
  something?
- What alternatives exist and how viable are they?

= Future work

- Prevent a submodule checkout when the submodule's HEAD is detached and
  not pointing to the superproject gitlink
- Implement the checkout -b/-B flags i.e. create a new branch
  recursively and check it out.
- Refactor out the common bits between this series and "git branch
  --recurse-submodules".
- Check for checkout options that are incompatible with
  --recurse-submodules
- Parallelize the submodule checkout
- Handle the submodule.recurse config value
- Possibly refactor out the "find submodules in the index" logic from
  builtin/submodule--helper.

[1] 961b130d20 (branch: add --recurse-submodules option for branch creation, 2022-01-28)
[2] https://lore.kernel.org/git/kl6lh7cjvpm3.fsf@chooglen-macbookpro.roam.corp.google.com

Glen Choo (1):
  checkout --recurse-submodules: checkout branches if configured

 builtin/checkout.c            | 142 +++++++++++++++++++++++++++++++++-
 submodule.c                   |   6 ++
 submodule.h                   |   9 +++
 t/t2013-checkout-submodule.sh |  90 +++++++++++++++++++++
 4 files changed, 243 insertions(+), 4 deletions(-)


base-commit: 679e3693aba0c17af60c031f7eef68f2296b8dad
-- 
2.33.GIT


             reply	other threads:[~2022-02-09  6:53 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-09  6:52 Glen Choo [this message]
2022-02-09  6:52 ` [PATCH 1/1] checkout --recurse-submodules: checkout branches if configured Glen Choo
2022-02-09  6:56 ` [PATCH 0/1] checkout: teach "git checkout" to checkout submodule branches Glen Choo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220209065236.36494-1-chooglen@google.com \
    --to=chooglen@google.com \
    --cc=emilyshaffer@google.com \
    --cc=git@vger.kernel.org \
    --cc=levraiphilippeblain@gmail.com \
    --cc=rsbecker@nexbridge.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox