Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Tobler <jtobler@gitlab.com>2023-10-02 21:41:05 +0300
committerJustin Tobler <jtobler@gitlab.com>2023-10-19 21:47:56 +0300
commit292eba6982e85b1e9967cefb7cd4e7620841c221 (patch)
treed5266fc0d45532c0185a3b515f972bd0857d4d0c
parent7b43096ae1894b21fbc7aa3cf65d644bcd7ff73d (diff)
localrepo: Support porcelain fetch option
When performing `git-fetch(1)` with the `porcelain` option, references are printed to stdout in an easy-to-parse format. This change introduces a `localrepo.FetchRemote()` configuration to enabled `porcelain` output.
-rw-r--r--internal/git/localrepo/remote.go8
-rw-r--r--internal/git/localrepo/remote_test.go31
2 files changed, 39 insertions, 0 deletions
diff --git a/internal/git/localrepo/remote.go b/internal/git/localrepo/remote.go
index 737ba230d..696512afb 100644
--- a/internal/git/localrepo/remote.go
+++ b/internal/git/localrepo/remote.go
@@ -52,6 +52,10 @@ type FetchOpts struct {
Tags FetchOptsTags
// DryRun, if enabled, performs the `git-fetch(1)` command without updating any references.
DryRun bool
+ // Porcelain controls `git-fetch(1)` command output and when enabled prints output in an
+ // easy-to-parse format. By default, `git-fetch(1)` output is suppressed by the `--quiet` flag.
+ // Therefore, the Verbose option must also be enabled to receive output.
+ Porcelain bool
// Stdout if set it would be used to redirect stdout stream into it.
Stdout io.Writer
// Stderr if set it would be used to redirect stderr stream into it.
@@ -207,6 +211,10 @@ func (opts FetchOpts) buildFlags() []git.Option {
flags = append(flags, git.Flag{Name: "--dry-run"})
}
+ if opts.Porcelain {
+ flags = append(flags, git.Flag{Name: "--porcelain"})
+ }
+
// Even if we ask Git to not print any output and to force-update branches it will still
// compute whether branches have been force-updated only to discard that information again.
// Let's ask it not to given that this check can be quite expensive.
diff --git a/internal/git/localrepo/remote_test.go b/internal/git/localrepo/remote_test.go
index 25c4e7ddc..138428253 100644
--- a/internal/git/localrepo/remote_test.go
+++ b/internal/git/localrepo/remote_test.go
@@ -188,6 +188,37 @@ func TestRepo_FetchRemote(t *testing.T) {
require.Len(t, refs, 0)
})
+ t.Run("with porcelain", func(t *testing.T) {
+ repo, _ := initBareWithRemote(t, "origin")
+
+ // The porcelain fetch option write output to stdout in an easy-to-parse format. By default,
+ // output is suppressed by the --quiet flag. The Verbose option must also be enabled to
+ // receive output.
+ var stdout bytes.Buffer
+ require.NoError(t, repo.FetchRemote(ctx, "origin", FetchOpts{
+ Stdout: &stdout,
+ Porcelain: true,
+ Verbose: true,
+ }))
+
+ hash, err := repo.ObjectHash(ctx)
+ require.NoError(t, err)
+ scanner := git.NewFetchPorcelainScanner(&stdout, hash)
+
+ // Scan the output for expected references.
+ require.True(t, scanner.Scan())
+ require.Equal(t, git.RefUpdateTypeFetched, scanner.StatusLine().Type)
+ require.Equal(t, "refs/remotes/origin/main", scanner.StatusLine().Reference)
+ require.True(t, scanner.Scan())
+ require.Equal(t, git.RefUpdateTypeFetched, scanner.StatusLine().Type)
+ require.Equal(t, "refs/tags/v1.0.0", scanner.StatusLine().Reference)
+
+ // Since the remote only contains two references, there should be nothing left in the buffer
+ // to scan.
+ require.False(t, scanner.Scan())
+ require.Nil(t, scanner.Err())
+ })
+
t.Run("with no tags", func(t *testing.T) {
repo, testRepoPath := initBareWithRemote(t, "origin")