Merge pull request #765 from thockin/v4_fix_relative_submodules

Make relative-path submodules work, via origin
This commit is contained in:
Kubernetes Prow Robot 2023-07-10 11:44:52 -07:00 committed by GitHub
commit 5a9037f8c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 14 deletions

43
main.go
View File

@ -1208,6 +1208,8 @@ func (git *repoSync) RunWithStdin(ctx context.Context, cwd absPath, stdin string
// not, it will (re)initialize it. After running this function, callers can // not, it will (re)initialize it. After running this function, callers can
// assume the repo is valid, though maybe empty. // assume the repo is valid, though maybe empty.
func (git *repoSync) initRepo(ctx context.Context) error { func (git *repoSync) initRepo(ctx context.Context) error {
needGitInit := false
// Check out the git root, and see if it is already usable. // Check out the git root, and see if it is already usable.
_, err := os.Stat(git.root.String()) _, err := os.Stat(git.root.String())
switch { switch {
@ -1218,6 +1220,7 @@ func (git *repoSync) initRepo(ctx context.Context) error {
if err := os.MkdirAll(git.root.String(), defaultDirMode); err != nil { if err := os.MkdirAll(git.root.String(), defaultDirMode); err != nil {
return err return err
} }
needGitInit = true
case err != nil: case err != nil:
return err return err
default: default:
@ -1225,7 +1228,6 @@ func (git *repoSync) initRepo(ctx context.Context) error {
git.log.V(3).Info("repo directory exists", "path", git.root) git.log.V(3).Info("repo directory exists", "path", git.root)
if git.sanityCheckRepo(ctx) { if git.sanityCheckRepo(ctx) {
git.log.V(4).Info("repo directory is valid", "path", git.root) git.log.V(4).Info("repo directory is valid", "path", git.root)
return nil
} else { } else {
// Maybe a previous run crashed? Git won't use this dir. We remove // Maybe a previous run crashed? Git won't use this dir. We remove
// the contents rather than the dir itself, because a common use-case // the contents rather than the dir itself, because a common use-case
@ -1235,17 +1237,38 @@ func (git *repoSync) initRepo(ctx context.Context) error {
if err := removeDirContents(git.root, git.log); err != nil { if err := removeDirContents(git.root, git.log); err != nil {
return fmt.Errorf("can't wipe unusable root directory: %w", err) return fmt.Errorf("can't wipe unusable root directory: %w", err)
} }
needGitInit = true
} }
} }
// Running `git init` in an existing repo is safe (according to git docs). if needGitInit {
git.log.V(0).Info("initializing repo directory", "path", git.root) // Running `git init` in an existing repo is safe (according to git docs).
if _, _, err := git.Run(ctx, git.root, "init", "-b", "git-sync"); err != nil { git.log.V(0).Info("initializing repo directory", "path", git.root)
return err if _, _, err := git.Run(ctx, git.root, "init", "-b", "git-sync"); err != nil {
return err
}
if !git.sanityCheckRepo(ctx) {
return fmt.Errorf("can't initialize git repo directory")
}
} }
if !git.sanityCheckRepo(ctx) {
return fmt.Errorf("can't initialize git repo directory") // The "origin" remote has special meaning, like in relative-path
// submodules.
if stdout, stderr, err := git.Run(ctx, git.root, "remote", "get-url", "origin"); err != nil {
if !strings.Contains(stderr, "No such remote") {
return err
}
// It doesn't exist - make it.
if _, _, err := git.Run(ctx, git.root, "remote", "add", "origin", git.repo); err != nil {
return err
}
} else if strings.TrimSpace(stdout) != git.repo {
// It exists, but is wrong.
if _, _, err := git.Run(ctx, git.root, "remote", "set-url", "origin", git.repo); err != nil {
return err
}
} }
return nil return nil
} }
@ -1643,14 +1666,14 @@ func lastNonEmptyLine(text string) string {
// is not a hash or is not known to this repo, even if it appears to be a hash, // is not a hash or is not known to this repo, even if it appears to be a hash,
// this will return false. // this will return false.
func (git *repoSync) IsKnownHash(ctx context.Context, ref string) (bool, error) { func (git *repoSync) IsKnownHash(ctx context.Context, ref string) (bool, error) {
output, _, err := git.Run(ctx, git.root, "rev-parse", ref+"^{commit}") stdout, stderr, err := git.Run(ctx, git.root, "rev-parse", ref+"^{commit}")
if err != nil { if err != nil {
if strings.Contains(err.Error(), "unknown revision") { if strings.Contains(stderr, "unknown revision") {
return false, nil return false, nil
} }
return false, err return false, err
} }
line := lastNonEmptyLine(output) line := lastNonEmptyLine(stdout)
return strings.HasPrefix(line, ref), nil return strings.HasPrefix(line, ref), nil
} }

View File

@ -45,13 +45,14 @@ func NewRunner(log logintf) Runner {
return Runner{log: log} return Runner{log: log}
} }
// Run runs given command // Run runs the given command, returning the stdout, stderr, and any error.
func (r Runner) Run(ctx context.Context, cwd string, env []string, command string, args ...string) (string, string, error) { func (r Runner) Run(ctx context.Context, cwd string, env []string, command string, args ...string) (string, string, error) {
// call depth = 2 to erase the runWithStdin frame and this one // call depth = 2 to erase the runWithStdin frame and this one
return runWithStdin(ctx, r.log.WithCallDepth(2), cwd, env, "", command, args...) return runWithStdin(ctx, r.log.WithCallDepth(2), cwd, env, "", command, args...)
} }
// RunWithStdin runs given command with standard input // RunWithStdin runs the given command with standard input, returning the stdout,
// stderr, and any error.
func (r Runner) RunWithStdin(ctx context.Context, cwd string, env []string, stdin, command string, args ...string) (string, string, error) { func (r Runner) RunWithStdin(ctx context.Context, cwd string, env []string, stdin, command string, args ...string) (string, string, error) {
// call depth = 2 to erase the runWithStdin frame and this one // call depth = 2 to erase the runWithStdin frame and this one
return runWithStdin(ctx, r.log.WithCallDepth(2), cwd, env, stdin, command, args...) return runWithStdin(ctx, r.log.WithCallDepth(2), cwd, env, stdin, command, args...)
@ -80,10 +81,10 @@ func runWithStdin(ctx context.Context, log logintf, cwd string, env []string, st
stdout := strings.TrimSpace(outbuf.String()) stdout := strings.TrimSpace(outbuf.String())
stderr := strings.TrimSpace(errbuf.String()) stderr := strings.TrimSpace(errbuf.String())
if ctx.Err() == context.DeadlineExceeded { if ctx.Err() == context.DeadlineExceeded {
return "", "", fmt.Errorf("Run(%s): %w: { stdout: %q, stderr: %q }", cmdStr, ctx.Err(), stdout, stderr) return stdout, stderr, fmt.Errorf("Run(%s): %w: { stdout: %q, stderr: %q }", cmdStr, ctx.Err(), stdout, stderr)
} }
if err != nil { if err != nil {
return "", "", fmt.Errorf("Run(%s): %w: { stdout: %q, stderr: %q }", cmdStr, err, stdout, stderr) return stdout, stderr, fmt.Errorf("Run(%s): %w: { stdout: %q, stderr: %q }", cmdStr, err, stdout, stderr)
} }
log.V(6).Info("command result", "stdout", stdout, "stderr", stderr, "time", wallTime) log.V(6).Info("command result", "stdout", stdout, "stderr", stderr, "time", wallTime)

View File

@ -2527,6 +2527,42 @@ function e2e::submodule_sync_shallow() {
rm -rf $NESTED_SUBMODULE rm -rf $NESTED_SUBMODULE
} }
##############################################
# Test submodule sync with a relative path
##############################################
function e2e::submodule_sync_relative() {
# Init submodule repo
SUBMODULE_REPO_NAME="sub"
SUBMODULE="$WORK/$SUBMODULE_REPO_NAME"
mkdir "$SUBMODULE"
git -C "$SUBMODULE" init -q -b "$MAIN_BRANCH"
echo "submodule" > "$SUBMODULE/submodule"
git -C "$SUBMODULE" add submodule
git -C "$SUBMODULE" commit -aqm "init submodule file"
# Add submodule
REL="$(realpath --relative-to "$REPO" "$WORK/$SUBMODULE_REPO_NAME")"
echo $REL
git -C "$REPO" -c protocol.file.allow=always submodule add -q "${REL}"
git -C "$REPO" commit -aqm "add submodule"
GIT_SYNC \
--period=100ms \
--repo="file://$REPO" \
--root="$ROOT" \
--link="link" \
&
wait_for_sync "${MAXWAIT}"
assert_link_exists "$ROOT/link"
assert_file_exists "$ROOT/link/file"
assert_file_exists "$ROOT/link/$SUBMODULE_REPO_NAME/submodule"
assert_file_eq "$ROOT/link/$SUBMODULE_REPO_NAME/submodule" "submodule"
assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 1
rm -rf $SUBMODULE
}
############################################## ##############################################
# Test SSH # Test SSH
############################################## ##############################################