Archived
Restore puts submodules on a branch at their pin
A restored submodule whose pin is a branch tip ends on that branch instead of a detached HEAD: the local branch tracking the ref, else the ref created as a tracking branch, else another local branch, else another remote branch at the pin. No branch is moved; in-sync submodules are included (D28). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -327,17 +327,10 @@ func pinState(ctx context.Context, in info, st *submodule.Status, pin, head, bra
|
||||
return fmt.Errorf("pinned commit %.7s not fetched", pin)
|
||||
}
|
||||
|
||||
// remote branches containing the pin, oldest tip first
|
||||
out, err := run(ctx, in.dir, "for-each-ref", "--contains", pin, "--sort=committerdate", "--format=%(refname)", "refs/remotes")
|
||||
containing, err := remoteContaining(ctx, in.dir, pin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var containing []string
|
||||
for _, r := range strings.Fields(out) {
|
||||
if !strings.HasSuffix(r, "/HEAD") {
|
||||
containing = append(containing, strings.TrimPrefix(r, "refs/remotes/"))
|
||||
}
|
||||
}
|
||||
st.Pin.Pushed = len(containing) > 0
|
||||
|
||||
var ref string
|
||||
@@ -359,6 +352,7 @@ func pinState(ctx context.Context, in info, st *submodule.Status, pin, head, bra
|
||||
return err
|
||||
}
|
||||
st.CheckedOut = st.Pinned
|
||||
var out string
|
||||
if head != pin {
|
||||
if st.CheckedOut, err = commit(ctx, in.dir, head); err != nil {
|
||||
return err
|
||||
@@ -417,6 +411,22 @@ func pinState(ctx context.Context, in info, st *submodule.Status, pin, head, bra
|
||||
return nil
|
||||
}
|
||||
|
||||
// remoteContaining lists the remote branches containing pin, oldest tip
|
||||
// first, without the origin/HEAD symref.
|
||||
func remoteContaining(ctx context.Context, dir, pin string) ([]string, error) {
|
||||
out, err := run(ctx, dir, "for-each-ref", "--contains", pin, "--sort=committerdate", "--format=%(refname)", "refs/remotes")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var containing []string
|
||||
for _, r := range strings.Fields(out) {
|
||||
if !strings.HasSuffix(r, "/HEAD") {
|
||||
containing = append(containing, strings.TrimPrefix(r, "refs/remotes/"))
|
||||
}
|
||||
}
|
||||
return containing, nil
|
||||
}
|
||||
|
||||
// resolve finds the ref the pin is compared with, following the order in
|
||||
// docs/state-model.md: the target (see targetRef) if the pin is on it, else the
|
||||
// branch containing the pin that is closest to it, else the target anyway,
|
||||
|
||||
Reference in New Issue
Block a user