mirror of
https://github.com/haiwen/seafile-server.git
synced 2025-09-16 23:29:25 +00:00
Skip merge when post files with replace existed (#671)
* Skip merge when post files with replace existed * Use handle_concurrent_update to check if merge commits * Go handle concurrent update --------- Co-authored-by: 杨赫然 <heran.yang@seafile.com>
This commit is contained in:
@@ -1594,6 +1594,10 @@ func checkFilesWithSameName(repo *repomgr.Repo, canonPath string, fileNames []st
|
||||
}
|
||||
|
||||
func postFilesAndGenCommit(fileNames []string, repoID string, user, canonPath string, replace bool, ids []string, sizes []int64, lastModify int64) (string, error) {
|
||||
handleConncurrentUpdate := true
|
||||
if !replace {
|
||||
handleConncurrentUpdate = false
|
||||
}
|
||||
repo := repomgr.Get(repoID)
|
||||
if repo == nil {
|
||||
err := fmt.Errorf("failed to get repo %s", repoID)
|
||||
@@ -1635,7 +1639,7 @@ retry:
|
||||
buf = fmt.Sprintf("Added \"%s\".", fileNames[0])
|
||||
}
|
||||
|
||||
_, err = genNewCommit(repo, headCommit, rootID, user, buf, false)
|
||||
_, err = genNewCommit(repo, headCommit, rootID, user, buf, handleConncurrentUpdate)
|
||||
if err != nil {
|
||||
if err != ErrConflict {
|
||||
err := fmt.Errorf("failed to generate new commit: %v", err)
|
||||
@@ -1699,7 +1703,7 @@ func getCanonPath(p string) string {
|
||||
|
||||
var ErrConflict = fmt.Errorf("Concurent upload conflict")
|
||||
|
||||
func genNewCommit(repo *repomgr.Repo, base *commitmgr.Commit, newRoot, user, desc string, retryOnConflict bool) (string, error) {
|
||||
func genNewCommit(repo *repomgr.Repo, base *commitmgr.Commit, newRoot, user, desc string, handleConncurrentUpdate bool) (string, error) {
|
||||
var retryCnt int
|
||||
repoID := repo.ID
|
||||
commit := commitmgr.NewCommit(repoID, base.CommitID, newRoot, user, desc)
|
||||
@@ -1714,14 +1718,14 @@ func genNewCommit(repo *repomgr.Repo, base *commitmgr.Commit, newRoot, user, des
|
||||
maxRetryCnt := 10
|
||||
|
||||
for {
|
||||
retry, err := genCommitNeedRetry(repo, base, commit, newRoot, user, &commitID)
|
||||
retry, err := genCommitNeedRetry(repo, base, commit, newRoot, user, handleConncurrentUpdate, &commitID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !retry {
|
||||
break
|
||||
}
|
||||
if !retryOnConflict {
|
||||
if !handleConncurrentUpdate {
|
||||
return "", ErrConflict
|
||||
}
|
||||
|
||||
@@ -1747,7 +1751,7 @@ func genNewCommit(repo *repomgr.Repo, base *commitmgr.Commit, newRoot, user, des
|
||||
func fastForwardOrMerge(user string, repo *repomgr.Repo, base, newCommit *commitmgr.Commit) error {
|
||||
var retryCnt int
|
||||
for {
|
||||
retry, err := genCommitNeedRetry(repo, base, newCommit, newCommit.RootID, user, nil)
|
||||
retry, err := genCommitNeedRetry(repo, base, newCommit, newCommit.RootID, user, true, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1767,7 +1771,7 @@ func fastForwardOrMerge(user string, repo *repomgr.Repo, base, newCommit *commit
|
||||
return nil
|
||||
}
|
||||
|
||||
func genCommitNeedRetry(repo *repomgr.Repo, base *commitmgr.Commit, commit *commitmgr.Commit, newRoot, user string, commitID *string) (bool, error) {
|
||||
func genCommitNeedRetry(repo *repomgr.Repo, base *commitmgr.Commit, commit *commitmgr.Commit, newRoot, user string, handleConncurrentUpdate bool, commitID *string) (bool, error) {
|
||||
var secondParentID string
|
||||
repoID := repo.ID
|
||||
var mergeDesc string
|
||||
@@ -1779,6 +1783,9 @@ func genCommitNeedRetry(repo *repomgr.Repo, base *commitmgr.Commit, commit *comm
|
||||
}
|
||||
|
||||
if base.CommitID != currentHead.CommitID {
|
||||
if !handleConncurrentUpdate {
|
||||
return false, ErrConflict
|
||||
}
|
||||
roots := []string{base.RootID, currentHead.RootID, newRoot}
|
||||
opt := new(mergeOptions)
|
||||
opt.remoteRepoID = repoID
|
||||
|
@@ -456,7 +456,7 @@ gen_new_commit (const char *repo_id,
|
||||
const char *user,
|
||||
const char *desc,
|
||||
char *new_commit_id,
|
||||
gboolean retry_on_conflict,
|
||||
gboolean handle_concurrent_update,
|
||||
GError **error)
|
||||
{
|
||||
#define MAX_RETRY_COUNT 10
|
||||
@@ -503,6 +503,11 @@ retry:
|
||||
|
||||
/* Merge if base and head are not the same. */
|
||||
if (strcmp (base->commit_id, current_head->commit_id) != 0) {
|
||||
if (!handle_concurrent_update) {
|
||||
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_CONCURRENT_UPLOAD, "Concurrent upload");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
MergeOptions opt;
|
||||
const char *roots[3];
|
||||
char *desc = NULL;
|
||||
@@ -570,7 +575,7 @@ retry:
|
||||
repo->head,
|
||||
current_head->commit_id) < 0)
|
||||
{
|
||||
if (!retry_on_conflict) {
|
||||
if (!handle_concurrent_update) {
|
||||
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_CONCURRENT_UPLOAD, "Concurrent upload");
|
||||
ret = -1;
|
||||
goto out;
|
||||
@@ -1225,6 +1230,11 @@ post_files_and_gen_commit (GList *filenames,
|
||||
char *root_id = NULL;
|
||||
int ret = 0;
|
||||
int retry_cnt = 0;
|
||||
gboolean handle_concurrent_update = TRUE;
|
||||
|
||||
if (replace_existed == 0) {
|
||||
handle_concurrent_update = FALSE;
|
||||
}
|
||||
|
||||
GET_REPO_OR_FAIL(repo, repo_id);
|
||||
GET_COMMIT_OR_FAIL(head_commit, repo->id, repo->version, repo->head->commit_id);
|
||||
@@ -1250,7 +1260,7 @@ retry:
|
||||
g_string_printf (buf, "Added \"%s\".", (char *)(filenames->data));
|
||||
|
||||
if (gen_new_commit (repo->id, head_commit, root_id,
|
||||
user, buf->str, NULL, FALSE, error) < 0) {
|
||||
user, buf->str, NULL, handle_concurrent_update, error) < 0) {
|
||||
if (*error == NULL || (*error)->code != SEAF_ERR_CONCURRENT_UPLOAD) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
|
Reference in New Issue
Block a user