Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Dockerfile.in
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ RUN rm -rf \
/usr/lib/git-core/git-http-push \
/usr/lib/git-core/git-imap-send \
/usr/lib/git-core/git-instaweb \
/usr/lib/git-core/git-sh-i18n--envsubst \
/usr/lib/git-core/scalar \
/usr/lib/openssh/ssh-keysign \
/usr/lib/openssh/ssh-pkcs11-helper \
Expand Down
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,28 @@ OPTIONS
--git-config <string>, $GITSYNC_GIT_CONFIG
Additional git config options in a comma-separated 'key:val'
format. The parsed keys and values are passed to 'git config' and
must be valid syntax for that command.
must be valid syntax for that command. This is similar to
--git-config-add, but uses a single comma-separated string.

Both keys and values can be either quoted or unquoted strings.
Within quoted keys and all values (quoted or not), the following
escape sequences are supported:
'\n' => [newline]
'\t' => [tab]
'\"' => '"'
'\,' => ','
'\\' => '\'
To include a colon within a key (e.g. a URL) the key must be
quoted. Within unquoted values commas must be escaped. Within
quoted values commas may be escaped, but are not required to be.
Any other escape sequence is an error.

--git-config-add <string>
Add one git config option. The parsed key and value are passed to
'git config' and must be valid syntax for that command. This flag
can be specified more than once. This is similar to --git-config,
but allows multiple discrete uses of the flag instead of a single
comma-separated string.

Both keys and values can be either quoted or unquoted strings.
Within quoted keys and all values (quoted or not), the following
Expand Down
72 changes: 61 additions & 11 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"syscall"
"time"

"github.com/go-logr/logr/funcr"
"github.com/golang-jwt/jwt/v4"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
Expand Down Expand Up @@ -313,9 +314,12 @@ func main() {
flGitCmd := pflag.String("git",
envString("git", "GITSYNC_GIT", "GIT_SYNC_GIT"),
"the git command to run (subject to PATH search, mostly for testing)")
flGitConfig := pflag.String("git-config",
flGitConfigString := pflag.String("git-config",
envString("", "GITSYNC_GIT_CONFIG", "GIT_SYNC_GIT_CONFIG"),
"additional git config options in 'section.var1:val1,\"section.sub.var2\":\"val2\"' format")
flGitConfigList := pflag.StringArray("git-config-add", // Array vs. Slice to avoid CSV parsing
nil,
"add one additional git config option in 'section.var1:val1' format; can be repeated")
flGitGC := pflag.String("git-gc",
envString("always", "GITSYNC_GIT_GC", "GIT_SYNC_GIT_GC"),
"git garbage collection behavior: one of 'auto', 'always', 'aggressive', or 'off'")
Expand Down Expand Up @@ -810,13 +814,42 @@ func main() {
}

// This needs to be after all other git-related config flags.
if *flGitConfig != "" {
if err := git.SetupExtraGitConfigs(ctx, *flGitConfig); err != nil {
log.Error(err, "can't set additional git configs", "configs", *flGitConfig)
if *flGitConfigString != "" {
if err := git.SetupExtraGitConfigs(ctx, *flGitConfigString, "--git-config"); err != nil {
log.Error(err, "can't set additional git configs", "configs", *flGitConfigString)
os.Exit(1)
}
}
if len(*flGitConfigList) > 0 {
str := strings.Join(*flGitConfigList, ",")
if err := git.SetupExtraGitConfigs(ctx, str, "--git-config-add"); err != nil {
log.Error(err, "can't set additional git configs", "configs", str)
os.Exit(1)
}
}

// Log configs for debug. The -z means to produce a list of NUL-delimted KV
// pairs, where the first newline is the key/value separator and any
// additional newlines are part of the value.
if stdout, stderr, err := cmdRunner.Run(ctx, "", nil, *flGitCmd, "config", "list", "-z"); err != nil {
log.Error(err, "can't list git config")
os.Exit(1)
} else if stderr != "" {
log.V(0).Info("unexpected stderr reading git config", "stdout", stdout, "stderr", stderr)
os.Exit(1)
} else {
cfgs := strings.Split(stdout, string(rune(0)))
kvs := funcr.PseudoStruct{} // like a map but ordered
for _, cfg := range cfgs {
if cfg == "" {
continue
}
parts := strings.SplitN(cfg, "\n", 2) // any additional newlines are part of the value
kvs = append(kvs, parts[0], parts[1])
}
log.V(0).Info("git config", "configs", kvs)
}

// The scope of the initialization context ends here, so we call cancel to release resources associated with it.
cancel()

Expand Down Expand Up @@ -2259,10 +2292,6 @@ func (git *repoSync) SetupDefaultGitConfigs(ctx context.Context) error {
// Never prompt for a password.
key: "core.askPass",
val: "true",
}, {
// Mark repos as safe (avoid a "dubious ownership" error).
key: "safe.directory",
val: "*",
}}

for _, kv := range configs {
Expand All @@ -2275,10 +2304,10 @@ func (git *repoSync) SetupDefaultGitConfigs(ctx context.Context) error {

// SetupExtraGitConfigs configures the global git environment with user-provided
// override settings.
func (git *repoSync) SetupExtraGitConfigs(ctx context.Context, configsFlag string) error {
func (git *repoSync) SetupExtraGitConfigs(ctx context.Context, configsFlag string, flagName string) error {
configs, err := parseGitConfigs(configsFlag)
if err != nil {
return fmt.Errorf("can't parse --git-config flag: %w", err)
return fmt.Errorf("can't parse %s flag: %w", flagName, err)
}
git.log.V(1).Info("setting additional git configs", "configs", configs)
for _, kv := range configs {
Expand Down Expand Up @@ -2631,7 +2660,28 @@ OPTIONS
--git-config <string>, $GITSYNC_GIT_CONFIG
Additional git config options in a comma-separated 'key:val'
format. The parsed keys and values are passed to 'git config' and
must be valid syntax for that command.
must be valid syntax for that command. This is similar to
--git-config-add, but uses a single comma-separated string.

Both keys and values can be either quoted or unquoted strings.
Within quoted keys and all values (quoted or not), the following
escape sequences are supported:
'\n' => [newline]
'\t' => [tab]
'\"' => '"'
'\,' => ','
'\\' => '\'
To include a colon within a key (e.g. a URL) the key must be
quoted. Within unquoted values commas must be escaped. Within
quoted values commas may be escaped, but are not required to be.
Any other escape sequence is an error.

--git-config-add <string>
Add one git config option. The parsed key and value are passed to
'git config' and must be valid syntax for that command. This flag
can be specified more than once. This is similar to --git-config,
but allows multiple discrete uses of the flag instead of a single
comma-separated string.

Both keys and values can be either quoted or unquoted strings.
Within quoted keys and all values (quoted or not), the following
Expand Down
8 changes: 6 additions & 2 deletions test_e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,8 @@ function GIT_SYNC() {
--add-user \
--group-write \
--touch-file="$INTERLOCK" \
--git-config='protocol.file.allow:always' \
--git-config-add='protocol.file.allow:always' \
--git-config-add='safe.directory:*' \
--http-bind=":$HTTP_PORT" \
--http-metrics \
--http-pprof \
Expand Down Expand Up @@ -3573,7 +3574,10 @@ function e2e::additional_git_configs() {
--repo="file://$REPO" \
--root="$ROOT" \
--link="link" \
--git-config='http.postBuffer:10485760,sect.k1:"a val",sect.k2:another val'
--git-config='http.postBuffer:10485760,sect.k1:"a val",sect.k2:another val' \
--git-config-add='sect.k3:a val' \
--git-config-add='sect.k4:"a val with quotes"' \
--git-config-add='"sect.k5":"quoted_all"'
assert_link_exists "$ROOT/link"
assert_file_exists "$ROOT/link/file"
assert_file_eq "$ROOT/link/file" "${FUNCNAME[0]}"
Expand Down
Loading