From 01b9d35f1a0188dadc1ee09f5e4dd98acc38ff09 Mon Sep 17 00:00:00 2001
From: zeripath <art27@cantab.net>
Date: Wed, 13 Oct 2021 19:20:11 +0100
Subject: [PATCH] Disable core.protectNTFS (#17300)

core.protectNTFS protects NTFS from files which may be difficult to remove or interact
with using the win32 api, however, it also appears to prevent such files from
being entered into the git indexes - fundamentally causing breakages with PRs that
affect these files. However, deliberately setting this to false may cause security
issues due to the remain sparse checkout of files in the merge pipeline.

The only sensible option therefore is to provide an optional setting which admins
could set which would forcibly switch this off if they are affected by this issue.

Fix #17092

Signed-off-by: Andrew Thornton <art27@cantab.net>
---
 custom/conf/app.example.ini                           | 2 ++
 docs/content/doc/advanced/config-cheat-sheet.en-us.md | 1 +
 modules/git/git.go                                    | 6 ++++++
 modules/setting/git.go                                | 1 +
 4 files changed, 10 insertions(+)

diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index 0a25e7e5cd..07ca9f8409 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -580,6 +580,8 @@ PATH =
 ;;
 ;; (Go-Git only) Don't cache objects greater than this in memory. (Set to 0 to disable.)
 ;LARGE_OBJECT_THRESHOLD = 1048576
+;; Set to true to forcibly set core.protectNTFS=false
+;DISABLE_CORE_PROTECT_NTFS=false
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
index d224533e96..f02d8cbc37 100644
--- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md
+++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md
@@ -842,6 +842,7 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
 - `VERBOSE_PUSH`: **true**: Print status information about pushes as they are being processed.
 - `VERBOSE_PUSH_DELAY`: **5s**: Only print verbose information if push takes longer than this delay.
 - `LARGE_OBJECT_THRESHOLD`: **1048576**: (Go-Git only), don't cache objects greater than this in memory. (Set to 0 to disable.)
+- `DISABLE_CORE_PROTECT_NTFS`: **false** Set to true to forcibly set `core.protectNTFS` to false.
 ## Git - Timeout settings (`git.timeout`)
 - `DEFAUlT`: **360**: Git operations default timeout seconds.
 - `MIGRATE`: **600**: Migrate external repositories timeout seconds.
diff --git a/modules/git/git.go b/modules/git/git.go
index 7ab11736e8..e6c34979e8 100644
--- a/modules/git/git.go
+++ b/modules/git/git.go
@@ -204,6 +204,12 @@ func Init(ctx context.Context) error {
 			return err
 		}
 	}
+	if setting.Git.DisableCoreProtectNTFS {
+		if err := checkAndSetConfig("core.protectntfs", "false", true); err != nil {
+			return err
+		}
+		GlobalCommandArgs = append(GlobalCommandArgs, "-c", "core.protectntfs=false")
+	}
 	return nil
 }
 
diff --git a/modules/setting/git.go b/modules/setting/git.go
index aa838a8d64..aaa65ed81c 100644
--- a/modules/setting/git.go
+++ b/modules/setting/git.go
@@ -26,6 +26,7 @@ var (
 		EnableAutoGitWireProtocol bool
 		PullRequestPushMessage    bool
 		LargeObjectThreshold      int64
+		DisableCoreProtectNTFS    bool
 		Timeout                   struct {
 			Default int
 			Migrate int