Fixed support for worktree
Issue is that during 'git worktree add', git uses GIT_DIR to locate the worktree girder, which then resolves via commondir. When actually running in the worktree, it follows .git/git-dir THEN commondir. Generalised so this now works, and introduced LocalGitStorageDir.
This commit is contained in:
parent
416950783e
commit
66ebac22a7
@ -83,7 +83,7 @@ func doFsck() (bool, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
badDir := filepath.Join(lfs.LocalGitDir, "lfs", "bad")
|
badDir := filepath.Join(lfs.LocalGitStorageDir, "lfs", "bad")
|
||||||
if err := os.MkdirAll(badDir, 0755); err != nil {
|
if err := os.MkdirAll(badDir, 0755); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
49
lfs/lfs.go
49
lfs/lfs.go
@ -25,6 +25,7 @@ var (
|
|||||||
UserAgent string
|
UserAgent string
|
||||||
LocalWorkingDir string
|
LocalWorkingDir string
|
||||||
LocalGitDir string
|
LocalGitDir string
|
||||||
|
LocalGitStorageDir string // parent of objects/lfs (may be same as LocalGitDir but may not)
|
||||||
LocalMediaDir string
|
LocalMediaDir string
|
||||||
LocalLogDir string
|
LocalLogDir string
|
||||||
checkedTempDir string
|
checkedTempDir string
|
||||||
@ -69,13 +70,16 @@ func ObjectExistsOfSize(sha string, size int64) bool {
|
|||||||
|
|
||||||
func Environ() []string {
|
func Environ() []string {
|
||||||
osEnviron := os.Environ()
|
osEnviron := os.Environ()
|
||||||
env := make([]string, 6, len(osEnviron)+6)
|
env := make([]string, 7, len(osEnviron)+7)
|
||||||
env[0] = fmt.Sprintf("LocalWorkingDir=%s", LocalWorkingDir)
|
env = append(env,
|
||||||
env[1] = fmt.Sprintf("LocalGitDir=%s", LocalGitDir)
|
fmt.Sprintf("LocalWorkingDir=%s", LocalWorkingDir),
|
||||||
env[2] = fmt.Sprintf("LocalMediaDir=%s", LocalMediaDir)
|
fmt.Sprintf("LocalGitDir=%s", LocalGitDir),
|
||||||
env[3] = fmt.Sprintf("TempDir=%s", TempDir)
|
fmt.Sprintf("LocalGitStorageDir=%s", LocalGitStorageDir),
|
||||||
env[4] = fmt.Sprintf("ConcurrentTransfers=%d", Config.ConcurrentTransfers())
|
fmt.Sprintf("LocalMediaDir=%s", LocalMediaDir),
|
||||||
env[5] = fmt.Sprintf("BatchTransfer=%v", Config.BatchTransfer())
|
fmt.Sprintf("TempDir=%s", TempDir),
|
||||||
|
fmt.Sprintf("ConcurrentTransfers=%d", Config.ConcurrentTransfers()),
|
||||||
|
fmt.Sprintf("BatchTransfer=%v", Config.BatchTransfer()),
|
||||||
|
)
|
||||||
|
|
||||||
for _, e := range osEnviron {
|
for _, e := range osEnviron {
|
||||||
if !strings.Contains(e, "GIT_") {
|
if !strings.Contains(e, "GIT_") {
|
||||||
@ -99,9 +103,10 @@ func init() {
|
|||||||
|
|
||||||
LocalWorkingDir, LocalGitDir, err = resolveGitDir()
|
LocalWorkingDir, LocalGitDir, err = resolveGitDir()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
LocalMediaDir = filepath.Join(LocalGitDir, "lfs", "objects")
|
LocalGitStorageDir = resolveGitStorageDir(LocalGitDir)
|
||||||
|
LocalMediaDir = filepath.Join(LocalGitStorageDir, "lfs", "objects") // objects across all worktrees
|
||||||
LocalLogDir = filepath.Join(LocalMediaDir, "logs")
|
LocalLogDir = filepath.Join(LocalMediaDir, "logs")
|
||||||
TempDir = filepath.Join(LocalGitDir, "lfs", "tmp")
|
TempDir = filepath.Join(LocalGitDir, "lfs", "tmp") // temp files per worktree
|
||||||
|
|
||||||
if err := os.MkdirAll(LocalMediaDir, localMediaDirPerms); err != nil {
|
if err := os.MkdirAll(LocalMediaDir, localMediaDirPerms); err != nil {
|
||||||
panic(fmt.Errorf("Error trying to create objects directory in '%s': %s", LocalMediaDir, err))
|
panic(fmt.Errorf("Error trying to create objects directory in '%s': %s", LocalMediaDir, err))
|
||||||
@ -257,18 +262,26 @@ func processGitRedirectFile(file, prefix string) (string, error) {
|
|||||||
dir = filepath.Join(filepath.Dir(file), dir)
|
dir = filepath.Join(filepath.Dir(file), dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, check the contents of dir; if it contains a "commondir" file and
|
|
||||||
// not an "objects" dir, then this is probably a worktree link (see man git-worktree)
|
|
||||||
// The commondir file points to the actual location
|
|
||||||
commondirpath := filepath.Join(dir, "commondir")
|
|
||||||
if FileExists(commondirpath) && !DirExists(filepath.Join(dir, "objects")) {
|
|
||||||
// no git-dir: prefix in commondir
|
|
||||||
return processGitRedirectFile(commondirpath, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
return dir, nil
|
return dir, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From a git dir, get the location that objects are to be stored (we will store lfs alongside)
|
||||||
|
// Sometimes there is an additional level of redirect on the .git folder by way of a commondir file
|
||||||
|
// before you find object storage, e.g. 'git worktree' uses this. It redirects to gitdir either by GIT_DIR
|
||||||
|
// (during setup) or .git/git-dir: (during use), but this only contains the index etc, the objects
|
||||||
|
// are found in another git dir via 'commondir'.
|
||||||
|
func resolveGitStorageDir(gitDir string) string {
|
||||||
|
commondirpath := filepath.Join(gitDir, "commondir")
|
||||||
|
if FileExists(commondirpath) && !DirExists(filepath.Join(gitDir, "objects")) {
|
||||||
|
// no git-dir: prefix in commondir
|
||||||
|
storage, err := processGitRedirectFile(commondirpath, "")
|
||||||
|
if err == nil {
|
||||||
|
return storage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gitDir
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
gitExt = ".git"
|
gitExt = ".git"
|
||||||
gitPtrPrefix = "gitdir: "
|
gitPtrPrefix = "gitdir: "
|
||||||
|
@ -13,6 +13,7 @@ begin_test "env with no remote"
|
|||||||
expected=$(printf "%s\n%s\n
|
expected=$(printf "%s\n%s\n
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame
|
LocalWorkingDir=$TRASHDIR/$reponame
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=3
|
ConcurrentTransfers=3
|
||||||
@ -37,6 +38,7 @@ begin_test "env with origin remote"
|
|||||||
Endpoint=$GITSERVER/$reponame.git/info/lfs
|
Endpoint=$GITSERVER/$reponame.git/info/lfs
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame
|
LocalWorkingDir=$TRASHDIR/$reponame
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=3
|
ConcurrentTransfers=3
|
||||||
@ -68,6 +70,7 @@ Endpoint=$GITSERVER/env-origin-remote.git/info/lfs
|
|||||||
Endpoint (other)=$GITSERVER/env-other-remote.git/info/lfs
|
Endpoint (other)=$GITSERVER/env-other-remote.git/info/lfs
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame
|
LocalWorkingDir=$TRASHDIR/$reponame
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=3
|
ConcurrentTransfers=3
|
||||||
@ -97,6 +100,7 @@ begin_test "env with other remote"
|
|||||||
Endpoint (other)=$GITSERVER/env-other-remote.git/info/lfs
|
Endpoint (other)=$GITSERVER/env-other-remote.git/info/lfs
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame
|
LocalWorkingDir=$TRASHDIR/$reponame
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=3
|
ConcurrentTransfers=3
|
||||||
@ -129,6 +133,7 @@ Endpoint=http://foo/bar
|
|||||||
Endpoint (other)=$GITSERVER/env-other-remote.git/info/lfs
|
Endpoint (other)=$GITSERVER/env-other-remote.git/info/lfs
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame
|
LocalWorkingDir=$TRASHDIR/$reponame
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=3
|
ConcurrentTransfers=3
|
||||||
@ -163,6 +168,7 @@ Endpoint=http://foo/bar
|
|||||||
Endpoint (other)=http://custom/other
|
Endpoint (other)=http://custom/other
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame
|
LocalWorkingDir=$TRASHDIR/$reponame
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=3
|
ConcurrentTransfers=3
|
||||||
@ -199,6 +205,7 @@ Endpoint=http://foo/bar
|
|||||||
Endpoint (other)=http://custom/other
|
Endpoint (other)=http://custom/other
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame
|
LocalWorkingDir=$TRASHDIR/$reponame
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=5
|
ConcurrentTransfers=5
|
||||||
@ -235,6 +242,7 @@ begin_test "env with .gitconfig"
|
|||||||
Endpoint=http://foobar:8080/
|
Endpoint=http://foobar:8080/
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame
|
LocalWorkingDir=$TRASHDIR/$reponame
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=5
|
ConcurrentTransfers=5
|
||||||
@ -265,6 +273,7 @@ begin_test "env with environment variables"
|
|||||||
expected=$(printf "%s\n%s\n
|
expected=$(printf "%s\n%s\n
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame/a/b
|
LocalWorkingDir=$TRASHDIR/$reponame/a/b
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=3
|
ConcurrentTransfers=3
|
||||||
@ -290,6 +299,7 @@ $(GIT_DIR=$gitDir GIT_WORK_TREE=$workTree env | grep "^GIT")
|
|||||||
expected5=$(printf "%s\n%s\n
|
expected5=$(printf "%s\n%s\n
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame/a/b
|
LocalWorkingDir=$TRASHDIR/$reponame/a/b
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=3
|
ConcurrentTransfers=3
|
||||||
@ -302,6 +312,7 @@ $(GIT_DIR=$gitDir GIT_WORK_TREE=a/b env | grep "^GIT")
|
|||||||
expected6=$(printf "%s\n%s\n
|
expected6=$(printf "%s\n%s\n
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame/a/b
|
LocalWorkingDir=$TRASHDIR/$reponame/a/b
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=3
|
ConcurrentTransfers=3
|
||||||
@ -315,6 +326,7 @@ $(GIT_WORK_TREE=a/b env | grep "^GIT")
|
|||||||
expected7=$(printf "%s\n%s\n
|
expected7=$(printf "%s\n%s\n
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame/a/b
|
LocalWorkingDir=$TRASHDIR/$reponame/a/b
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=3
|
ConcurrentTransfers=3
|
||||||
@ -328,6 +340,7 @@ $(GIT_DIR=$gitDir env | grep "^GIT")
|
|||||||
expected8=$(printf "%s\n%s\n
|
expected8=$(printf "%s\n%s\n
|
||||||
LocalWorkingDir=$TRASHDIR/$reponame/a/b
|
LocalWorkingDir=$TRASHDIR/$reponame/a/b
|
||||||
LocalGitDir=$TRASHDIR/$reponame/.git
|
LocalGitDir=$TRASHDIR/$reponame/.git
|
||||||
|
LocalGitStorageDir=$LocalGitDir
|
||||||
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
LocalMediaDir=$TRASHDIR/$reponame/.git/lfs/objects
|
||||||
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
TempDir=$TRASHDIR/$reponame/.git/lfs/tmp
|
||||||
ConcurrentTransfers=3
|
ConcurrentTransfers=3
|
||||||
|
@ -43,6 +43,7 @@ begin_test "submodule env"
|
|||||||
grep "Endpoint=$GITSERVER/$reponame.git/info/lfs$" env.log
|
grep "Endpoint=$GITSERVER/$reponame.git/info/lfs$" env.log
|
||||||
grep "LocalWorkingDir=$TRASHDIR/repo$" env.log
|
grep "LocalWorkingDir=$TRASHDIR/repo$" env.log
|
||||||
grep "LocalGitDir=$TRASHDIR/repo/.git$" env.log
|
grep "LocalGitDir=$TRASHDIR/repo/.git$" env.log
|
||||||
|
grep "LocalGitStorageDir=$TRASHDIR/repo/.git$" env.log
|
||||||
grep "LocalMediaDir=$TRASHDIR/repo/.git/lfs/objects$" env.log
|
grep "LocalMediaDir=$TRASHDIR/repo/.git/lfs/objects$" env.log
|
||||||
grep "TempDir=$TRASHDIR/repo/.git/lfs/tmp$" env.log
|
grep "TempDir=$TRASHDIR/repo/.git/lfs/tmp$" env.log
|
||||||
|
|
||||||
@ -53,6 +54,7 @@ begin_test "submodule env"
|
|||||||
grep "Endpoint=$GITSERVER/$reponame.git/info/lfs$" env.log
|
grep "Endpoint=$GITSERVER/$reponame.git/info/lfs$" env.log
|
||||||
grep "LocalWorkingDir=$" env.log
|
grep "LocalWorkingDir=$" env.log
|
||||||
grep "LocalGitDir=$TRASHDIR/repo/.git$" env.log
|
grep "LocalGitDir=$TRASHDIR/repo/.git$" env.log
|
||||||
|
grep "LocalGitStorageDir=$TRASHDIR/repo/.git$" env.log
|
||||||
grep "LocalMediaDir=$TRASHDIR/repo/.git/lfs/objects$" env.log
|
grep "LocalMediaDir=$TRASHDIR/repo/.git/lfs/objects$" env.log
|
||||||
grep "TempDir=$TRASHDIR/repo/.git/lfs/tmp$" env.log
|
grep "TempDir=$TRASHDIR/repo/.git/lfs/tmp$" env.log
|
||||||
|
|
||||||
@ -63,6 +65,7 @@ begin_test "submodule env"
|
|||||||
grep "Endpoint=$GITSERVER/$submodname.git/info/lfs$" env.log
|
grep "Endpoint=$GITSERVER/$submodname.git/info/lfs$" env.log
|
||||||
grep "LocalWorkingDir=$TRASHDIR/repo/sub$" env.log
|
grep "LocalWorkingDir=$TRASHDIR/repo/sub$" env.log
|
||||||
grep "LocalGitDir=$TRASHDIR/repo/.git/modules/sub$" env.log
|
grep "LocalGitDir=$TRASHDIR/repo/.git/modules/sub$" env.log
|
||||||
|
grep "LocalGitStorageDir=$TRASHDIR/repo/.git$" env.log
|
||||||
grep "LocalMediaDir=$TRASHDIR/repo/.git/modules/sub/lfs/objects$" env.log
|
grep "LocalMediaDir=$TRASHDIR/repo/.git/modules/sub/lfs/objects$" env.log
|
||||||
grep "TempDir=$TRASHDIR/repo/.git/modules/sub/lfs/tmp$" env.log
|
grep "TempDir=$TRASHDIR/repo/.git/modules/sub/lfs/tmp$" env.log
|
||||||
|
|
||||||
@ -73,6 +76,7 @@ begin_test "submodule env"
|
|||||||
grep "Endpoint=$GITSERVER/$submodname.git/info/lfs$" env.log
|
grep "Endpoint=$GITSERVER/$submodname.git/info/lfs$" env.log
|
||||||
grep "LocalWorkingDir=$TRASHDIR/repo/sub$" env.log
|
grep "LocalWorkingDir=$TRASHDIR/repo/sub$" env.log
|
||||||
grep "LocalGitDir=$TRASHDIR/repo/.git/modules/sub$" env.log
|
grep "LocalGitDir=$TRASHDIR/repo/.git/modules/sub$" env.log
|
||||||
|
grep "LocalGitStorageDir=$TRASHDIR/repo/.git$" env.log
|
||||||
grep "LocalMediaDir=$TRASHDIR/repo/.git/modules/sub/lfs/objects$" env.log
|
grep "LocalMediaDir=$TRASHDIR/repo/.git/modules/sub/lfs/objects$" env.log
|
||||||
grep "TempDir=$TRASHDIR/repo/.git/modules/sub/lfs/tmp$" env.log
|
grep "TempDir=$TRASHDIR/repo/.git/modules/sub/lfs/tmp$" env.log
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user