feat: Use receive.hideRefs (#10015)
In forgejo/forgejo!2834 and forgejo/forgejo!5307 it was made so it's no longer possible to modify and delete internal reference, not having this restriction lead to broken pull requests when people used something like `git push --mirror`. However it now still leads to problem with that command as the git client tries to delete such references. We can solve this by using git's `receive.hideRefs` to make this ref read-only and avoid advertising it when someone does `git push --mirror`. Resolves forgejo/forgejo#9942 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10015 Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org> Co-authored-by: Gusted <postmaster@gusted.xyz> Co-committed-by: Gusted <postmaster@gusted.xyz>
This commit is contained in:
+1
-29
@@ -295,35 +295,7 @@ Forgejo or set your environment appropriately.`, "")
|
||||
|
||||
// runHookUpdate process the update hook: https://git-scm.com/docs/githooks#update
|
||||
func runHookUpdate(ctx context.Context, c *cli.Command) error {
|
||||
// Now if we're an internal don't do anything else
|
||||
if isInternal, _ := strconv.ParseBool(os.Getenv(repo_module.EnvIsInternal)); isInternal {
|
||||
return nil
|
||||
}
|
||||
|
||||
ctx, cancel := installSignals(ctx)
|
||||
defer cancel()
|
||||
|
||||
if c.NArg() != 3 {
|
||||
return nil
|
||||
}
|
||||
args := c.Args().Slice()
|
||||
|
||||
// The arguments given to the hook are in order: reference name, old commit ID and new commit ID.
|
||||
refFullName := git.RefName(args[0])
|
||||
newCommitID := args[2]
|
||||
|
||||
// Only process pull references.
|
||||
if !refFullName.IsPull() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Empty new commit ID means deletion.
|
||||
if git.IsEmptyCommitID(newCommitID, nil) {
|
||||
return fail(ctx, fmt.Sprintf("The deletion of %s is skipped as it's an internal reference.", refFullName), "")
|
||||
}
|
||||
|
||||
// If the new comment isn't empty it means modification.
|
||||
return fail(ctx, fmt.Sprintf("The modification of %s is skipped as it's an internal reference.", refFullName), "")
|
||||
return nil
|
||||
}
|
||||
|
||||
func runHookPostReceive(ctx context.Context, c *cli.Command) error {
|
||||
|
||||
@@ -161,42 +161,3 @@ func TestDelayWriter(t *testing.T) {
|
||||
require.Empty(t, out)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRunHookUpdate(t *testing.T) {
|
||||
app := cli.Command{}
|
||||
app.Commands = []*cli.Command{subcmdHookUpdate()}
|
||||
|
||||
t.Run("Removal of internal reference", func(t *testing.T) {
|
||||
defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
|
||||
defer test.MockVariableValue(&setting.IsProd, false)()
|
||||
finish := captureOutput(t, os.Stderr)
|
||||
|
||||
err := app.Run(t.Context(), []string{"./forgejo", "update", "refs/pull/1/head", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000000"})
|
||||
out := finish()
|
||||
require.Error(t, err)
|
||||
|
||||
assert.Contains(t, out, "The deletion of refs/pull/1/head is skipped as it's an internal reference.")
|
||||
})
|
||||
|
||||
t.Run("Update of internal reference", func(t *testing.T) {
|
||||
defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
|
||||
defer test.MockVariableValue(&setting.IsProd, false)()
|
||||
finish := captureOutput(t, os.Stderr)
|
||||
|
||||
err := app.Run(t.Context(), []string{"./forgejo", "update", "refs/pull/1/head", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000001"})
|
||||
out := finish()
|
||||
require.Error(t, err)
|
||||
|
||||
assert.Contains(t, out, "The modification of refs/pull/1/head is skipped as it's an internal reference.")
|
||||
})
|
||||
|
||||
t.Run("Removal of branch", func(t *testing.T) {
|
||||
err := app.Run(t.Context(), []string{"./forgejo", "update", "refs/head/main", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000000"})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Not enough arguments", func(t *testing.T) {
|
||||
err := app.Run(t.Context(), []string{"./forgejo", "update"})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user