From c0226f28c666cd152707215ae336a3d52857b880 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Mon, 29 Jul 2019 00:26:36 -0300 Subject: [PATCH 01/17] Add support for AUTO_WATCH_ON_CHANGES and AUTO_WATCH_ON_CLONE --- custom/conf/app.ini.sample | 8 + .../doc/advanced/config-cheat-sheet.en-us.md | 2 + models/repo_watch.go | 149 +++++++++++++++--- modules/setting/service.go | 4 + routers/private/serv.go | 14 ++ routers/repo/http.go | 31 ++++ 6 files changed, 188 insertions(+), 20 deletions(-) diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index 991a2a3e6b4b1..e02ac98fcfe21 100644 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -424,6 +424,14 @@ SHOW_REGISTRATION_BUTTON = true ; When adding a repo to a team or creating a new repo all team members will watch the ; repo automatically if enabled AUTO_WATCH_NEW_REPOS = true +; Default value for AutoWatchOnChanges +; When pushing changes (git-receive-pack), the user will watch the repo +; automatically if enabled +AUTO_WATCH_ON_CHANGES = false +; Default value for AutoWatchOnClone +; When pulling changes (git-upload-pack), the user will watch the repo +; automatically if enabled +AUTO_WATCH_ON_CLONE = false [webhook] ; Hook task queue length, increase if webhook shooting starts hanging 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 6f3bc465a659a..fe4b17996ba47 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -242,6 +242,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. on this instance. - `SHOW_REGISTRATION_BUTTON`: **! DISABLE\_REGISTRATION**: Show Registration Button - `AUTO_WATCH_NEW_REPOS`: **true**: Enable this to let all organisation users watch new repos when they are created +- `AUTO_WATCH_ON_CHANGES`: **false**: Enable this to make users watch repos when they push any changes +- `AUTO_WATCH_ON_CLONE`: **false**: Enable this to make users watch repos when they fetch from them - `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private". ## Webhook (`webhook`) diff --git a/models/repo_watch.go b/models/repo_watch.go index 53a34efdafea0..dec187146ea61 100644 --- a/models/repo_watch.go +++ b/models/repo_watch.go @@ -4,42 +4,124 @@ package models -import "fmt" +import ( + "fmt" + + "code.gitea.io/gitea/modules/setting" +) + +// RepoWatchMode specifies what kind of watch the user has on a repository +type RepoWatchMode int8 + +const ( + // RepoWatchModeNone don't watch + RepoWatchModeNone RepoWatchMode = iota // 0 + // RepoWatchModeNormal watch repository (from other sources) + RepoWatchModeNormal // 1 + // RepoWatchModeDont explicit don't auto-watch + RepoWatchModeDont // 2 + // RepoWatchModeAuto watch repository (from AutoWatchOnChanges) + RepoWatchModeAuto // 3 +) // Watch is connection request for receiving repository notification. type Watch struct { - ID int64 `xorm:"pk autoincr"` - UserID int64 `xorm:"UNIQUE(watch)"` - RepoID int64 `xorm:"UNIQUE(watch)"` + ID int64 `xorm:"pk autoincr"` + UserID int64 `xorm:"UNIQUE(watch)"` + RepoID int64 `xorm:"UNIQUE(watch)"` + Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` } -func isWatching(e Engine, userID, repoID int64) bool { - has, _ := e.Get(&Watch{UserID: userID, RepoID: repoID}) - return has +// getWatch gets what kind of subscription a user has on a given repository; returns dummy record if none found +func getWatch(e Engine, userID, repoID int64) (Watch, error) { + watch := Watch{UserID: userID, RepoID: repoID} + has, err := e.Get(&watch) + if err != nil { + return watch, err + } + if !has { + watch.Mode = RepoWatchModeNone + } + return watch, nil +} + +// Decodes watchability of RepoWatchMode +func isWatchMode(mode RepoWatchMode) bool { + return mode != RepoWatchModeNone && mode != RepoWatchModeDont } // IsWatching checks if user has watched given repository. func IsWatching(userID, repoID int64) bool { - return isWatching(x, userID, repoID) + watch, err := getWatch(x, userID, repoID) + return err == nil && isWatchMode(watch.Mode) } -func watchRepo(e Engine, userID, repoID int64, watch bool) (err error) { - if watch { - if isWatching(e, userID, repoID) { - return nil +func watchRepoMode(e Engine, watch Watch, mode RepoWatchMode) (err error) { + if watch.Mode == mode { + return nil + } + if mode == RepoWatchModeAuto && isWatchMode(watch.Mode) { + // Don't auto watch if already watching + return nil + } + if mode == RepoWatchModeAuto && watch.Mode == RepoWatchModeDont { + // Don't auto watch if explicitly not watching + return nil + } + + hadrec := watch.Mode != RepoWatchModeNone + needsrec := mode != RepoWatchModeNone + repodiff := 0 + + if isWatchMode(mode) && !isWatchMode(watch.Mode) { + repodiff = 1 + } else if !isWatchMode(mode) && isWatchMode(watch.Mode) { + repodiff = -1 + } + + watch.Mode = mode + + if !hadrec && needsrec { + watch.Mode = mode + if _, err = e.Insert(watch); err != nil { + return err } - if _, err = e.Insert(&Watch{RepoID: repoID, UserID: userID}); err != nil { + } else if needsrec { + watch.Mode = mode + if _, err := e.ID(watch.ID).AllCols().Update(watch); err != nil { return err } - _, err = e.Exec("UPDATE `repository` SET num_watches = num_watches + 1 WHERE id = ?", repoID) } else { - if !isWatching(e, userID, repoID) { - return nil - } - if _, err = e.Delete(&Watch{0, userID, repoID}); err != nil { + if _, err = e.Delete(Watch{ID: watch.ID}); err != nil { return err } - _, err = e.Exec("UPDATE `repository` SET num_watches = num_watches - 1 WHERE id = ?", repoID) + } + if repodiff != 0 { + _, err = e.Exec("UPDATE `repository` SET num_watches = num_watches + ? WHERE id = ?", repodiff, watch.RepoID) + } + return err +} + +// WatchRepoMode watch repository in specific mode. +func WatchRepoMode(userID, repoID int64, mode RepoWatchMode) (err error) { + var watch Watch + if watch, err = getWatch(x, userID, repoID); err != nil { + return err + } + return watchRepoMode(x, watch, mode) +} + +func watchRepo(e Engine, userID, repoID int64, doWatch bool) (err error) { + var watch Watch + if watch, err = getWatch(e, userID, repoID); err != nil { + return err + } + if !doWatch && watch.Mode == RepoWatchModeAuto { + err = watchRepoMode(e, watch, RepoWatchModeDont) + } else if !doWatch { + err = watchRepoMode(e, watch, RepoWatchModeNone) + } else { + err = watchRepoMode(e, watch, RepoWatchModeNormal) } return err } @@ -52,6 +134,7 @@ func WatchRepo(userID, repoID int64, watch bool) (err error) { func getWatchers(e Engine, repoID int64) ([]*Watch, error) { watches := make([]*Watch, 0, 10) return watches, e.Where("`watch`.repo_id=?", repoID). + And("`watch`.mode<>?", RepoWatchModeDont). And("`user`.is_active=?", true). And("`user`.prohibit_login=?", false). Join("INNER", "`user`", "`user`.id = `watch`.user_id"). @@ -67,7 +150,8 @@ func GetWatchers(repoID int64) ([]*Watch, error) { func (repo *Repository) GetWatchers(page int) ([]*User, error) { users := make([]*User, 0, ItemsPerPage) sess := x.Where("watch.repo_id=?", repo.ID). - Join("LEFT", "watch", "`user`.id=`watch`.user_id") + Join("LEFT", "watch", "`user`.id=`watch`.user_id"). + And("`watch`.mode<>?", RepoWatchModeDont) if page > 0 { sess = sess.Limit(ItemsPerPage, (page-1)*ItemsPerPage) } @@ -137,3 +221,28 @@ func notifyWatchers(e Engine, act *Action) error { func NotifyWatchers(act *Action) error { return notifyWatchers(x, act) } + +func watchIfAuto(e Engine, userID, repoID int64, isWrite bool) error { + if isWrite { + if !setting.Service.AutoWatchOnClone { + return nil + } + } else { + if !setting.Service.AutoWatchOnChanges { + return nil + } + } + watch, err := getWatch(e, userID, repoID) + if err != nil { + return err + } + if watch.Mode != RepoWatchModeNone { + return nil + } + return watchRepoMode(e, watch, RepoWatchModeAuto) +} + +// WatchIfAuto subscribes to repo if AutoWatchOnClone or AutoWatchOnChanges are set +func WatchIfAuto(userID int64, repoID int64, isWrite bool) error { + return watchIfAuto(x, userID, repoID, isWrite) +} diff --git a/modules/setting/service.go b/modules/setting/service.go index 97babc5aaf215..eebb72b2b1da3 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -42,6 +42,8 @@ var Service struct { NoReplyAddress string EnableUserHeatmap bool AutoWatchNewRepos bool + AutoWatchOnChanges bool + AutoWatchOnClone bool // OpenID settings EnableOpenIDSignIn bool @@ -80,6 +82,8 @@ func newService() { Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply.example.org") Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true) Service.AutoWatchNewRepos = sec.Key("AUTO_WATCH_NEW_REPOS").MustBool(true) + Service.AutoWatchOnChanges = sec.Key("AUTO_WATCH_ON_CHANGES").MustBool(false) + Service.AutoWatchOnClone = sec.Key("AUTO_WATCH_ON_CLONE").MustBool(false) Service.DefaultOrgVisibility = sec.Key("DEFAULT_ORG_VISIBILITY").In("public", structs.ExtractKeysFromMapString(structs.VisibilityModes)) Service.DefaultOrgVisibilityMode = structs.VisibilityModes[Service.DefaultOrgVisibility] diff --git a/routers/private/serv.go b/routers/private/serv.go index 90579a3dcce16..a6b3c1247b95f 100644 --- a/routers/private/serv.go +++ b/routers/private/serv.go @@ -268,6 +268,20 @@ func ServCommand(ctx *macaron.Context) { return } } + + // Auto-subscribe to repo if not anonymous user and not wiki + if !results.IsWiki && user != nil { + if err = models.WatchIfAuto(user.ID, repo.ID, mode == models.AccessModeWrite); err != nil { + log.Error("Failed to check auto watch for user %-v on %-v Error: %v", user, repo, err) + ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ + "results": results, + "type": "InternalServerError", + "err": fmt.Sprintf("Failed to check auto watch for user %s on repo %s Error: %v", user.Name, repo.Name, err), + }) + return + } + } + log.Debug("Serv Results:\nIsWiki: %t\nIsDeployKey: %t\nKeyID: %d\tKeyName: %s\nUserName: %s\nUserID: %d\nOwnerName: %s\nRepoName: %s\nRepoID: %d", results.IsWiki, results.IsDeployKey, diff --git a/routers/repo/http.go b/routers/repo/http.go index a9a5cedc20792..4b569fbcccd86 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -26,6 +26,8 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + + "github.com/Unknwon/com" ) // HTTP implmentation git smart HTTP protocol @@ -430,6 +432,35 @@ func serviceRPC(h serviceHandler, service string) { log.Error("Fail to serve RPC(%s): %v - %v", service, err, stderr) return } + + // Implement automatic watch on upload/receive + if service != "upload-pack" && service != "receive-pack" { + return + } + + var ( + repoID int64 + userID int64 + ) + + // Restore userID and repoID values from context + repoReg := regexp.MustCompile("^" + models.ProtectedBranchRepoID + "=(.*)$") + userReg := regexp.MustCompile("^" + models.EnvPusherID + "=(.*)$") + + for _, env := range h.environ { + if m := repoReg.FindStringSubmatch(env); m != nil { + repoID = com.StrTo(m[1]).MustInt64() + } + if m := userReg.FindStringSubmatch(env); m != nil { + userID = com.StrTo(m[1]).MustInt64() + } + } + + if userID == 0 || repoID == 0 { + return + } + + models.WatchIfAuto(userID, repoID, service == "receive-pack") } func serviceUploadPack(h serviceHandler) { From 6c1a0391aa401da69ebaf1324761aa4ebec1ec8d Mon Sep 17 00:00:00 2001 From: guillep2k Date: Mon, 29 Jul 2019 11:25:48 -0300 Subject: [PATCH 02/17] Update models/repo_watch.go Co-Authored-By: Lauris BH --- models/repo_watch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/repo_watch.go b/models/repo_watch.go index dec187146ea61..e4da69c5bd707 100644 --- a/models/repo_watch.go +++ b/models/repo_watch.go @@ -60,7 +60,7 @@ func watchRepoMode(e Engine, watch Watch, mode RepoWatchMode) (err error) { if watch.Mode == mode { return nil } - if mode == RepoWatchModeAuto && isWatchMode(watch.Mode) { + if mode == RepoWatchModeAuto && (watch.Mode == RepoWatchModeDont || isWatchMode(watch.Mode)) { // Don't auto watch if already watching return nil } From 5d52dda8698079565a47e7d5e1a15b41b2c79495 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Mon, 29 Jul 2019 11:43:58 -0300 Subject: [PATCH 03/17] Round up changes suggested by lafriks --- models/repo_watch.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/models/repo_watch.go b/models/repo_watch.go index e4da69c5bd707..4a7c8a6356f95 100644 --- a/models/repo_watch.go +++ b/models/repo_watch.go @@ -64,10 +64,6 @@ func watchRepoMode(e Engine, watch Watch, mode RepoWatchMode) (err error) { // Don't auto watch if already watching return nil } - if mode == RepoWatchModeAuto && watch.Mode == RepoWatchModeDont { - // Don't auto watch if explicitly not watching - return nil - } hadrec := watch.Mode != RepoWatchModeNone needsrec := mode != RepoWatchModeNone From 6e4a28d8c7ee5c59693de1c81217c28b91db4fcd Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Mon, 29 Jul 2019 12:06:30 -0300 Subject: [PATCH 04/17] Added changes suggested from automated tests --- models/repo_watch.go | 6 ++---- routers/repo/http.go | 5 ++++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/models/repo_watch.go b/models/repo_watch.go index 4a7c8a6356f95..8bc353037a03c 100644 --- a/models/repo_watch.go +++ b/models/repo_watch.go @@ -87,10 +87,8 @@ func watchRepoMode(e Engine, watch Watch, mode RepoWatchMode) (err error) { if _, err := e.ID(watch.ID).AllCols().Update(watch); err != nil { return err } - } else { - if _, err = e.Delete(Watch{ID: watch.ID}); err != nil { - return err - } + } else if _, err = e.Delete(Watch{ID: watch.ID}); err != nil { + return err } if repodiff != 0 { _, err = e.Exec("UPDATE `repository` SET num_watches = num_watches + ? WHERE id = ?", repodiff, watch.RepoID) diff --git a/routers/repo/http.go b/routers/repo/http.go index 4b569fbcccd86..2a8f25aef31e4 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -460,7 +460,10 @@ func serviceRPC(h serviceHandler, service string) { return } - models.WatchIfAuto(userID, repoID, service == "receive-pack") + if err = models.WatchIfAuto(userID, repoID, service == "receive-pack"); err != nil { + log.Warn("Fail to perform auto watch on user %v for repo %v: %v - %v", userID, repoID, err, stderr) + return + } } func serviceUploadPack(h serviceHandler) { From ce99d457ecf7fc842c85aee25baaea926bdf6b5b Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Tue, 30 Jul 2019 18:01:03 -0300 Subject: [PATCH 05/17] Updated deleteUser to take RepoWatchModeDont into account, corrected inverted DefaultWatchOnClone and DefaultWatchOnChanges behaviour, updated and added tests. --- models/consistency.go | 7 ++- models/fixtures/repository.yml | 2 +- models/fixtures/watch.yml | 15 +++++ models/repo.go | 4 +- models/repo_watch.go | 4 +- models/repo_watch_test.go | 108 ++++++++++++++++++++++++++++++++- models/user.go | 2 +- 7 files changed, 133 insertions(+), 9 deletions(-) diff --git a/models/consistency.go b/models/consistency.go index f9fa3028fd9c8..62d1d2e874a6a 100644 --- a/models/consistency.go +++ b/models/consistency.go @@ -84,14 +84,17 @@ func (user *User) checkForConsistency(t *testing.T) { func (repo *Repository) checkForConsistency(t *testing.T) { assert.Equal(t, repo.LowerName, strings.ToLower(repo.Name), "repo: %+v", repo) assertCount(t, &Star{RepoID: repo.ID}, repo.NumStars) - assertCount(t, &Watch{RepoID: repo.ID}, repo.NumWatches) assertCount(t, &Milestone{RepoID: repo.ID}, repo.NumMilestones) assertCount(t, &Repository{ForkID: repo.ID}, repo.NumForks) if repo.IsFork { AssertExistsAndLoadBean(t, &Repository{ID: repo.ForkID}) } - actual := getCount(t, x.Where("is_pull=?", false), &Issue{RepoID: repo.ID}) + actual := getCount(t, x.Where("Mode<>?", RepoWatchModeDont), &Watch{RepoID: repo.ID}) + assert.EqualValues(t, repo.NumWatches, actual, + "Unexpected number of watches for repo %+v", repo) + + actual = getCount(t, x.Where("is_pull=?", false), &Issue{RepoID: repo.ID}) assert.EqualValues(t, repo.NumIssues, actual, "Unexpected number of issues for repo %+v", repo) diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index f43fae3d67e88..5c63c058d41fe 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -10,7 +10,7 @@ num_closed_pulls: 0 num_milestones: 3 num_closed_milestones: 1 - num_watches: 3 + num_watches: 4 - id: 2 diff --git a/models/fixtures/watch.yml b/models/fixtures/watch.yml index 5cd3b55fc43e1..322297f022aaa 100644 --- a/models/fixtures/watch.yml +++ b/models/fixtures/watch.yml @@ -2,13 +2,28 @@ id: 1 user_id: 1 repo_id: 1 + mode: 1 # normal - id: 2 user_id: 4 repo_id: 1 + mode: 1 # normal - id: 3 user_id: 9 repo_id: 1 + mode: 1 # normal + +- + id: 4 + user_id: 8 + repo_id: 1 + mode: 2 # don't watch + +- + id: 5 + user_id: 11 + repo_id: 1 + mode: 3 # auto \ No newline at end of file diff --git a/models/repo.go b/models/repo.go index ba14155395746..08fc7444bc190 100644 --- a/models/repo.go +++ b/models/repo.go @@ -2261,8 +2261,8 @@ func CheckRepoStats() { checkers := []*repoChecker{ // Repository.NumWatches { - "SELECT repo.id FROM `repository` repo WHERE repo.num_watches!=(SELECT COUNT(*) FROM `watch` WHERE repo_id=repo.id)", - "UPDATE `repository` SET num_watches=(SELECT COUNT(*) FROM `watch` WHERE repo_id=?) WHERE id=?", + "SELECT repo.id FROM `repository` repo WHERE repo.num_watches!=(SELECT COUNT(*) FROM `watch` WHERE repo_id=repo.id AND mode<>2)", + "UPDATE `repository` SET num_watches=(SELECT COUNT(*) FROM `watch` WHERE repo_id=? AND mode<>2) WHERE id=?", "repository count 'num_watches'", }, // Repository.NumStars diff --git a/models/repo_watch.go b/models/repo_watch.go index 8bc353037a03c..ea00646441c79 100644 --- a/models/repo_watch.go +++ b/models/repo_watch.go @@ -218,11 +218,11 @@ func NotifyWatchers(act *Action) error { func watchIfAuto(e Engine, userID, repoID int64, isWrite bool) error { if isWrite { - if !setting.Service.AutoWatchOnClone { + if !setting.Service.AutoWatchOnChanges { return nil } } else { - if !setting.Service.AutoWatchOnChanges { + if !setting.Service.AutoWatchOnClone { return nil } } diff --git a/models/repo_watch_test.go b/models/repo_watch_test.go index 852f09f1c7e0c..edee6199b4ef3 100644 --- a/models/repo_watch_test.go +++ b/models/repo_watch_test.go @@ -7,6 +7,8 @@ package models import ( "testing" + "code.gitea.io/gitea/modules/setting" + "github.com/stretchr/testify/assert" ) @@ -15,8 +17,10 @@ func TestIsWatching(t *testing.T) { assert.True(t, IsWatching(1, 1)) assert.True(t, IsWatching(4, 1)) + assert.True(t, IsWatching(11, 1)) assert.False(t, IsWatching(1, 5)) + assert.False(t, IsWatching(8, 1)) assert.False(t, IsWatching(NonexistentID, NonexistentID)) } @@ -78,7 +82,7 @@ func TestNotifyWatchers(t *testing.T) { } assert.NoError(t, NotifyWatchers(action)) - // One watchers are inactive, thus action is only created for user 8, 1, 4 + // One watchers are inactive, thus action is only created for user 8, 1, 4, 11 AssertExistsAndLoadBean(t, &Action{ ActUserID: action.ActUserID, UserID: 8, @@ -97,4 +101,106 @@ func TestNotifyWatchers(t *testing.T) { RepoID: action.RepoID, OpType: action.OpType, }) + AssertExistsAndLoadBean(t, &Action{ + ActUserID: action.ActUserID, + UserID: 11, + RepoID: action.RepoID, + OpType: action.OpType, + }) +} + +func TestWatchIfAuto(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + + repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) + watchers, err := repo.GetWatchers(1) + assert.NoError(t, err) + assert.Len(t, watchers, repo.NumWatches) + + setting.Service.AutoWatchOnClone = false + setting.Service.AutoWatchOnChanges = false + + prevCount := repo.NumWatches + + // Must not add watch + assert.NoError(t, WatchIfAuto(8, 1, false)) + watchers, err = repo.GetWatchers(1) + assert.NoError(t, err) + assert.Len(t, watchers, prevCount) + + // Should not add watch + assert.NoError(t, WatchIfAuto(10, 1, false)) + watchers, err = repo.GetWatchers(1) + assert.NoError(t, err) + assert.Len(t, watchers, prevCount) + + setting.Service.AutoWatchOnClone = true + + // Should not add watch + assert.NoError(t, WatchIfAuto(10, 1, true)) + watchers, err = repo.GetWatchers(1) + assert.NoError(t, err) + assert.Len(t, watchers, prevCount) + + // Should add watch + assert.NoError(t, WatchIfAuto(10, 1, false)) + watchers, err = repo.GetWatchers(1) + assert.NoError(t, err) + assert.Len(t, watchers, prevCount+1) + + prevCount++ + + setting.Service.AutoWatchOnClone = false + setting.Service.AutoWatchOnChanges = true + + // Must not add watch + assert.NoError(t, WatchIfAuto(8, 1, false)) + watchers, err = repo.GetWatchers(1) + assert.NoError(t, err) + assert.Len(t, watchers, prevCount) + + // Should not add watch + assert.NoError(t, WatchIfAuto(12, 1, false)) + watchers, err = repo.GetWatchers(1) + assert.NoError(t, err) + assert.Len(t, watchers, prevCount) + + // Should add watch + assert.NoError(t, WatchIfAuto(12, 1, true)) + watchers, err = repo.GetWatchers(1) + assert.NoError(t, err) + assert.Len(t, watchers, prevCount+1) + + // Should remove watch, inhibit from adding auto + assert.NoError(t, WatchRepo(12, 1, false)) + watchers, err = repo.GetWatchers(1) + assert.NoError(t, err) + assert.Len(t, watchers, prevCount) + + // Must not add watch + assert.NoError(t, WatchIfAuto(12, 1, false)) + watchers, err = repo.GetWatchers(1) + assert.NoError(t, err) + assert.Len(t, watchers, prevCount) +} + +func TestWatchRepoMode(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + + AssertCount(t, &Watch{UserID: 12, RepoID: 1}, 0) + + assert.NoError(t, WatchRepoMode(12, 1, RepoWatchModeAuto)) + AssertCount(t, &Watch{UserID: 12, RepoID: 1}, 1) + AssertCount(t, &Watch{UserID: 12, RepoID: 1, Mode: RepoWatchModeAuto}, 1) + + assert.NoError(t, WatchRepoMode(12, 1, RepoWatchModeNormal)) + AssertCount(t, &Watch{UserID: 12, RepoID: 1}, 1) + AssertCount(t, &Watch{UserID: 12, RepoID: 1, Mode: RepoWatchModeNormal}, 1) + + assert.NoError(t, WatchRepoMode(12, 1, RepoWatchModeDont)) + AssertCount(t, &Watch{UserID: 12, RepoID: 1}, 1) + AssertCount(t, &Watch{UserID: 12, RepoID: 1, Mode: RepoWatchModeDont}, 1) + + assert.NoError(t, WatchRepoMode(12, 1, RepoWatchModeNone)) + AssertCount(t, &Watch{UserID: 12, RepoID: 1}, 0) } diff --git a/models/user.go b/models/user.go index 1f684a594045a..acf03f1089212 100644 --- a/models/user.go +++ b/models/user.go @@ -1047,7 +1047,7 @@ func deleteUser(e *xorm.Session, u *User) error { // ***** START: Watch ***** watchedRepoIDs := make([]int64, 0, 10) if err = e.Table("watch").Cols("watch.repo_id"). - Where("watch.user_id = ?", u.ID).Find(&watchedRepoIDs); err != nil { + Where("watch.user_id = ?", u.ID).And("watch.mode <>?", RepoWatchModeDont).Find(&watchedRepoIDs); err != nil { return fmt.Errorf("get all watches: %v", err) } if _, err = e.Decr("num_watches").In("id", watchedRepoIDs).NoAutoTime().Update(new(Repository)); err != nil { From 2abd4137c778d658200555bc2bdfb3e508618599 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Thu, 15 Aug 2019 12:00:50 -0300 Subject: [PATCH 06/17] Reinsert import "github.com/Unknwon/com" on http.go --- routers/repo/http.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/routers/repo/http.go b/routers/repo/http.go index d0c517526f681..f7463b30b90ed 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -26,6 +26,8 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + + "github.com/Unknwon/com" ) // HTTP implmentation git smart HTTP protocol From 3034d5e9279da0155c90ee1c053ed5866e85e74e Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Thu, 15 Aug 2019 20:06:57 -0300 Subject: [PATCH 07/17] Add migration for new column `watch`.`mode` --- models/migrations/migrations.go | 2 ++ models/migrations/v93.go | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 models/migrations/v93.go diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 9ffcfb4df2005..ab78e0f7f3ee0 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -240,6 +240,8 @@ var migrations = []Migration{ NewMigration("add index on owner_id of repository and type, review_id of comment", addIndexOnRepositoryAndComment), // v92 -> v93 NewMigration("remove orphaned repository index statuses", removeLingeringIndexStatus), + // v93 -> v94 + NewMigration("add column `mode` to table watch", addModeColumnToWatch), } // Migrate database to current version diff --git a/models/migrations/v93.go b/models/migrations/v93.go new file mode 100644 index 0000000000000..25b2048255c42 --- /dev/null +++ b/models/migrations/v93.go @@ -0,0 +1,25 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import ( + "github.com/go-xorm/xorm" +) + +// RepoWatchMode specifies what kind of watch the user has on a repository +type RepoWatchMode int8 + +// Watch is connection request for receiving repository notification. +type Watch struct { + ID int64 `xorm:"pk autoincr"` + UserID int64 `xorm:"UNIQUE(watch)"` + RepoID int64 `xorm:"UNIQUE(watch)"` + Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` +} + +func addModeColumnToWatch(x *xorm.Engine) error { + + return x.Sync2(new(Watch)) +} From 6715664ce4e0047f98c8645cdf8eb6d684a671fb Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Mon, 26 Aug 2019 22:22:06 -0300 Subject: [PATCH 08/17] Remove serv code --- modules/repofiles/update.go | 5 +++++ routers/private/serv.go | 14 -------------- routers/repo/http.go | 34 ---------------------------------- 3 files changed, 5 insertions(+), 48 deletions(-) diff --git a/modules/repofiles/update.go b/modules/repofiles/update.go index ee1b16bce9dbd..cf82fe2e8d4a6 100644 --- a/modules/repofiles/update.go +++ b/modules/repofiles/update.go @@ -502,5 +502,10 @@ func PushUpdate(repo *models.Repository, branch string, opts models.PushUpdateOp if opts.RefFullName == git.BranchPrefix+repo.DefaultBranch { models.UpdateRepoIndexer(repo) } + + if err = models.WatchIfAuto(opts.PusherID, repo.ID, true); err != nil { + log.Warn("Fail to perform auto watch on user %v for repo %v: %v", opts.PusherID, repo.ID, err) + } + return nil } diff --git a/routers/private/serv.go b/routers/private/serv.go index a7166f5a2115c..71c0f6ea2c48c 100644 --- a/routers/private/serv.go +++ b/routers/private/serv.go @@ -268,20 +268,6 @@ func ServCommand(ctx *macaron.Context) { return } } - - // Auto-subscribe to repo if not anonymous user and not wiki - if !results.IsWiki && user != nil { - if err = models.WatchIfAuto(user.ID, repo.ID, mode == models.AccessModeWrite); err != nil { - log.Error("Failed to check auto watch for user %-v on %-v Error: %v", user, repo, err) - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ - "results": results, - "type": "InternalServerError", - "err": fmt.Sprintf("Failed to check auto watch for user %s on repo %s Error: %v", user.Name, repo.Name, err), - }) - return - } - } - log.Debug("Serv Results:\nIsWiki: %t\nIsDeployKey: %t\nKeyID: %d\tKeyName: %s\nUserName: %s\nUserID: %d\nOwnerName: %s\nRepoName: %s\nRepoID: %d", results.IsWiki, results.IsDeployKey, diff --git a/routers/repo/http.go b/routers/repo/http.go index f7463b30b90ed..09dd8205852cf 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -26,8 +26,6 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" - - "github.com/Unknwon/com" ) // HTTP implmentation git smart HTTP protocol @@ -432,38 +430,6 @@ func serviceRPC(h serviceHandler, service string) { log.Error("Fail to serve RPC(%s): %v - %s", service, err, stderr.String()) return } - - // Implement automatic watch on upload/receive - if service != "upload-pack" && service != "receive-pack" { - return - } - - var ( - repoID int64 - userID int64 - ) - - // Restore userID and repoID values from context - repoReg := regexp.MustCompile("^" + models.ProtectedBranchRepoID + "=(.*)$") - userReg := regexp.MustCompile("^" + models.EnvPusherID + "=(.*)$") - - for _, env := range h.environ { - if m := repoReg.FindStringSubmatch(env); m != nil { - repoID = com.StrTo(m[1]).MustInt64() - } - if m := userReg.FindStringSubmatch(env); m != nil { - userID = com.StrTo(m[1]).MustInt64() - } - } - - if userID == 0 || repoID == 0 { - return - } - - if err = models.WatchIfAuto(userID, repoID, service == "receive-pack"); err != nil { - log.Warn("Fail to perform auto watch on user %v for repo %v: %v - %v", userID, repoID, err, stderr) - return - } } func serviceUploadPack(h serviceHandler) { From 00782cf37f1115166c6ec743034ff87c829637d5 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Tue, 27 Aug 2019 01:18:15 -0300 Subject: [PATCH 09/17] Remove WATCH_ON_CLONE; use hooks, add integrations --- custom/conf/app.ini.sample | 4 ---- .../doc/advanced/config-cheat-sheet.en-us.md | 1 - integrations/watch_test.go | 24 +++++++++++++++++++ models/migrations/v93.go | 4 ---- models/repo_watch.go | 7 +++--- models/repo_watch_test.go | 24 +++---------------- models/user.go | 1 + modules/setting/service.go | 2 -- 8 files changed, 31 insertions(+), 36 deletions(-) create mode 100644 integrations/watch_test.go diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index c8b35cb8cada0..9608d7f57f2ee 100644 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -437,10 +437,6 @@ AUTO_WATCH_NEW_REPOS = true ; When pushing changes (git-receive-pack), the user will watch the repo ; automatically if enabled AUTO_WATCH_ON_CHANGES = false -; Default value for AutoWatchOnClone -; When pulling changes (git-upload-pack), the user will watch the repo -; automatically if enabled -AUTO_WATCH_ON_CLONE = false [webhook] ; Hook task queue length, increase if webhook shooting starts hanging 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 e6b311c514ade..8dfee0f28defa 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -247,7 +247,6 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. - `SHOW_REGISTRATION_BUTTON`: **! DISABLE\_REGISTRATION**: Show Registration Button - `AUTO_WATCH_NEW_REPOS`: **true**: Enable this to let all organisation users watch new repos when they are created - `AUTO_WATCH_ON_CHANGES`: **false**: Enable this to make users watch repos when they push any changes -- `AUTO_WATCH_ON_CLONE`: **false**: Enable this to make users watch repos when they fetch from them - `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private". - `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation. diff --git a/integrations/watch_test.go b/integrations/watch_test.go new file mode 100644 index 0000000000000..c95e823039cd7 --- /dev/null +++ b/integrations/watch_test.go @@ -0,0 +1,24 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package integrations + +import ( + "net/url" + "testing" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/setting" +) + +func TestWatch(t *testing.T) { + onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { + // Test round-trip auto-watch + setting.Service.AutoWatchOnChanges = true + session := loginUser(t, "user2") + models.AssertNotExistsBean(t, &models.Watch{UserID:2, RepoID:3}) + testEditFile(t, session, "user3", "repo3", "master", "README.md", "Hello, World (Edited for watch)\n") + models.AssertExistsAndLoadBean(t, &models.Watch{UserID:2, RepoID:3, Mode:models.RepoWatchModeAuto}) + }) +} diff --git a/models/migrations/v93.go b/models/migrations/v93.go index 25b2048255c42..5064a2c6d4733 100644 --- a/models/migrations/v93.go +++ b/models/migrations/v93.go @@ -13,13 +13,9 @@ type RepoWatchMode int8 // Watch is connection request for receiving repository notification. type Watch struct { - ID int64 `xorm:"pk autoincr"` - UserID int64 `xorm:"UNIQUE(watch)"` - RepoID int64 `xorm:"UNIQUE(watch)"` Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` } func addModeColumnToWatch(x *xorm.Engine) error { - return x.Sync2(new(Watch)) } diff --git a/models/repo_watch.go b/models/repo_watch.go index ea00646441c79..46cb765f26caf 100644 --- a/models/repo_watch.go +++ b/models/repo_watch.go @@ -222,9 +222,8 @@ func watchIfAuto(e Engine, userID, repoID int64, isWrite bool) error { return nil } } else { - if !setting.Service.AutoWatchOnClone { - return nil - } + // No other kind of auto-watch for the moment + return nil } watch, err := getWatch(e, userID, repoID) if err != nil { @@ -236,7 +235,7 @@ func watchIfAuto(e Engine, userID, repoID int64, isWrite bool) error { return watchRepoMode(e, watch, RepoWatchModeAuto) } -// WatchIfAuto subscribes to repo if AutoWatchOnClone or AutoWatchOnChanges are set +// WatchIfAuto subscribes to repo if AutoWatchOnChanges is set func WatchIfAuto(userID int64, repoID int64, isWrite bool) error { return watchIfAuto(x, userID, repoID, isWrite) } diff --git a/models/repo_watch_test.go b/models/repo_watch_test.go index edee6199b4ef3..c3d40ec919822 100644 --- a/models/repo_watch_test.go +++ b/models/repo_watch_test.go @@ -117,44 +117,26 @@ func TestWatchIfAuto(t *testing.T) { assert.NoError(t, err) assert.Len(t, watchers, repo.NumWatches) - setting.Service.AutoWatchOnClone = false setting.Service.AutoWatchOnChanges = false prevCount := repo.NumWatches // Must not add watch - assert.NoError(t, WatchIfAuto(8, 1, false)) + assert.NoError(t, WatchIfAuto(8, 1, true)) watchers, err = repo.GetWatchers(1) assert.NoError(t, err) assert.Len(t, watchers, prevCount) - // Should not add watch - assert.NoError(t, WatchIfAuto(10, 1, false)) - watchers, err = repo.GetWatchers(1) - assert.NoError(t, err) - assert.Len(t, watchers, prevCount) - - setting.Service.AutoWatchOnClone = true - // Should not add watch assert.NoError(t, WatchIfAuto(10, 1, true)) watchers, err = repo.GetWatchers(1) assert.NoError(t, err) assert.Len(t, watchers, prevCount) - // Should add watch - assert.NoError(t, WatchIfAuto(10, 1, false)) - watchers, err = repo.GetWatchers(1) - assert.NoError(t, err) - assert.Len(t, watchers, prevCount+1) - - prevCount++ - - setting.Service.AutoWatchOnClone = false setting.Service.AutoWatchOnChanges = true // Must not add watch - assert.NoError(t, WatchIfAuto(8, 1, false)) + assert.NoError(t, WatchIfAuto(8, 1, true)) watchers, err = repo.GetWatchers(1) assert.NoError(t, err) assert.Len(t, watchers, prevCount) @@ -178,7 +160,7 @@ func TestWatchIfAuto(t *testing.T) { assert.Len(t, watchers, prevCount) // Must not add watch - assert.NoError(t, WatchIfAuto(12, 1, false)) + assert.NoError(t, WatchIfAuto(12, 1, true)) watchers, err = repo.GetWatchers(1) assert.NoError(t, err) assert.Len(t, watchers, prevCount) diff --git a/models/user.go b/models/user.go index dfad6af15ce89..7f06fb5a7329a 100644 --- a/models/user.go +++ b/models/user.go @@ -1504,6 +1504,7 @@ func GetStarredRepos(userID int64, private bool) ([]*Repository, error) { // GetWatchedRepos returns the repos watched by a particular user func GetWatchedRepos(userID int64, private bool) ([]*Repository, error) { sess := x.Where("watch.user_id=?", userID). + And("`watch`.mode<>?", RepoWatchModeDont). Join("LEFT", "watch", "`repository`.id=`watch`.repo_id") if !private { sess = sess.And("is_private=?", false) diff --git a/modules/setting/service.go b/modules/setting/service.go index b0fdb83e3b562..0ed12026d82f9 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -43,7 +43,6 @@ var Service struct { EnableUserHeatmap bool AutoWatchNewRepos bool AutoWatchOnChanges bool - AutoWatchOnClone bool DefaultOrgMemberVisible bool // OpenID settings @@ -84,7 +83,6 @@ func newService() { Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true) Service.AutoWatchNewRepos = sec.Key("AUTO_WATCH_NEW_REPOS").MustBool(true) Service.AutoWatchOnChanges = sec.Key("AUTO_WATCH_ON_CHANGES").MustBool(false) - Service.AutoWatchOnClone = sec.Key("AUTO_WATCH_ON_CLONE").MustBool(false) Service.DefaultOrgVisibility = sec.Key("DEFAULT_ORG_VISIBILITY").In("public", structs.ExtractKeysFromMapString(structs.VisibilityModes)) Service.DefaultOrgVisibilityMode = structs.VisibilityModes[Service.DefaultOrgVisibility] Service.DefaultOrgMemberVisible = sec.Key("DEFAULT_ORG_MEMBER_VISIBLE").MustBool() From ff09de9b175488d59627638b3dfb8a178fd20c16 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Tue, 27 Aug 2019 01:33:40 -0300 Subject: [PATCH 10/17] Renamed watch_test.go to repo_watch_test.go --- integrations/{watch_test.go => repo_watch_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename integrations/{watch_test.go => repo_watch_test.go} (100%) diff --git a/integrations/watch_test.go b/integrations/repo_watch_test.go similarity index 100% rename from integrations/watch_test.go rename to integrations/repo_watch_test.go From fde42fa01b31948775035b75b3c49ef999ada53d Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Tue, 27 Aug 2019 02:18:49 -0300 Subject: [PATCH 11/17] Correct fmt --- integrations/repo_watch_test.go | 4 ++-- models/migrations/v93.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/repo_watch_test.go b/integrations/repo_watch_test.go index c95e823039cd7..a3104e81c7f1d 100644 --- a/integrations/repo_watch_test.go +++ b/integrations/repo_watch_test.go @@ -17,8 +17,8 @@ func TestWatch(t *testing.T) { // Test round-trip auto-watch setting.Service.AutoWatchOnChanges = true session := loginUser(t, "user2") - models.AssertNotExistsBean(t, &models.Watch{UserID:2, RepoID:3}) + models.AssertNotExistsBean(t, &models.Watch{UserID: 2, RepoID: 3}) testEditFile(t, session, "user3", "repo3", "master", "README.md", "Hello, World (Edited for watch)\n") - models.AssertExistsAndLoadBean(t, &models.Watch{UserID:2, RepoID:3, Mode:models.RepoWatchModeAuto}) + models.AssertExistsAndLoadBean(t, &models.Watch{UserID: 2, RepoID: 3, Mode: models.RepoWatchModeAuto}) }) } diff --git a/models/migrations/v93.go b/models/migrations/v93.go index 5064a2c6d4733..0a9ae5a0617cc 100644 --- a/models/migrations/v93.go +++ b/models/migrations/v93.go @@ -13,7 +13,7 @@ type RepoWatchMode int8 // Watch is connection request for receiving repository notification. type Watch struct { - Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` + Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` } func addModeColumnToWatch(x *xorm.Engine) error { From 0969aa82e8f98d73856bd9e058e3e1eeb55af041 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Tue, 27 Aug 2019 02:31:01 -0300 Subject: [PATCH 12/17] Add missing EOL --- models/fixtures/watch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/fixtures/watch.yml b/models/fixtures/watch.yml index 322297f022aaa..c29f6bb65a889 100644 --- a/models/fixtures/watch.yml +++ b/models/fixtures/watch.yml @@ -26,4 +26,4 @@ id: 5 user_id: 11 repo_id: 1 - mode: 3 # auto \ No newline at end of file + mode: 3 # auto From 4a0d89e6cabe3165d968b5ae68e1161fa4ca9f40 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Tue, 27 Aug 2019 02:33:38 -0300 Subject: [PATCH 13/17] Correct name of test function --- integrations/repo_watch_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrations/repo_watch_test.go b/integrations/repo_watch_test.go index a3104e81c7f1d..d96b014a73618 100644 --- a/integrations/repo_watch_test.go +++ b/integrations/repo_watch_test.go @@ -12,7 +12,7 @@ import ( "code.gitea.io/gitea/modules/setting" ) -func TestWatch(t *testing.T) { +func TestRepoWatch(t *testing.T) { onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { // Test round-trip auto-watch setting.Service.AutoWatchOnChanges = true From de0852fceacd511d3d4feb48605af16d7a75df27 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Wed, 30 Oct 2019 22:18:14 -0300 Subject: [PATCH 14/17] Reword cheat and ini descriptions --- custom/conf/app.ini.sample | 3 +-- docs/content/doc/advanced/config-cheat-sheet.en-us.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index 386c692d0688b..491b799e8ddbb 100644 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -500,8 +500,7 @@ SHOW_REGISTRATION_BUTTON = true ; repo automatically if enabled AUTO_WATCH_NEW_REPOS = true ; Default value for AutoWatchOnChanges -; When pushing changes (git-receive-pack), the user will watch the repo -; automatically if enabled +; Make the user watch a repository When they commit for the first time AUTO_WATCH_ON_CHANGES = false [webhook] 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 5249bcd24ef3f..e7f3e10e910c0 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -302,7 +302,7 @@ relation to port exhaustion. on this instance. - `SHOW_REGISTRATION_BUTTON`: **! DISABLE\_REGISTRATION**: Show Registration Button - `AUTO_WATCH_NEW_REPOS`: **true**: Enable this to let all organisation users watch new repos when they are created -- `AUTO_WATCH_ON_CHANGES`: **false**: Enable this to make users watch repos when they push any changes +- `AUTO_WATCH_ON_CHANGES`: **false**: Enable this to make users watch a repository after their first commit to it - `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private". - `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation. From f0e6aeb96387e45939824fd492f79ba9084e0e40 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Sat, 2 Nov 2019 00:28:43 -0300 Subject: [PATCH 15/17] Add update to migration to ensure column value --- models/migrations/v105.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/models/migrations/v105.go b/models/migrations/v105.go index ee1bc4390a4bb..201fc10266a00 100644 --- a/models/migrations/v105.go +++ b/models/migrations/v105.go @@ -13,9 +13,14 @@ type RepoWatchMode int8 // Watch is connection request for receiving repository notification. type Watch struct { + ID int64 `xorm:"pk autoincr"` Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` } -func addModeColumnToWatch(x *xorm.Engine) error { - return x.Sync2(new(Watch)) +func addModeColumnToWatch(x *xorm.Engine) (err error) { + if err = x.Sync2(new(Watch)); err != nil { + return + } + _, err = x.Exec("UPDATE `watch` SET `mode` = 1") + return err } From 4341a4be84ca0c6ecd567b46673942319e7389a6 Mon Sep 17 00:00:00 2001 From: guillep2k <18600385+guillep2k@users.noreply.github.com> Date: Sun, 10 Nov 2019 00:15:08 -0300 Subject: [PATCH 16/17] Clarify comment Co-Authored-By: zeripath --- models/repo_watch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/repo_watch.go b/models/repo_watch.go index 46cb765f26caf..8262757947038 100644 --- a/models/repo_watch.go +++ b/models/repo_watch.go @@ -61,7 +61,7 @@ func watchRepoMode(e Engine, watch Watch, mode RepoWatchMode) (err error) { return nil } if mode == RepoWatchModeAuto && (watch.Mode == RepoWatchModeDont || isWatchMode(watch.Mode)) { - // Don't auto watch if already watching + // Don't auto watch if already watching or deliberately not watching return nil } From c59a2387dc012c9e52ad57a58b2ac4adde7f3329 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Sun, 10 Nov 2019 00:19:40 -0300 Subject: [PATCH 17/17] Simplify if condition --- models/repo_watch.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/models/repo_watch.go b/models/repo_watch.go index 8262757947038..cb864fb46dab0 100644 --- a/models/repo_watch.go +++ b/models/repo_watch.go @@ -217,12 +217,7 @@ func NotifyWatchers(act *Action) error { } func watchIfAuto(e Engine, userID, repoID int64, isWrite bool) error { - if isWrite { - if !setting.Service.AutoWatchOnChanges { - return nil - } - } else { - // No other kind of auto-watch for the moment + if !isWrite || !setting.Service.AutoWatchOnChanges { return nil } watch, err := getWatch(e, userID, repoID)