diff --git a/app/client/src/api/GitSyncAPI.tsx b/app/client/src/api/GitSyncAPI.tsx index 6488bbd0f6..ee90237784 100644 --- a/app/client/src/api/GitSyncAPI.tsx +++ b/app/client/src/api/GitSyncAPI.tsx @@ -172,8 +172,10 @@ class GitSyncAPI extends Api { }); } - static discardChanges(applicationId: string) { - return Api.put(`${GitSyncAPI.baseURL}/discard/app/${applicationId}`); + static discardChanges(applicationId: string, doPull: boolean) { + return Api.put( + `${GitSyncAPI.baseURL}/discard/app/${applicationId}?doPull=${doPull}`, + ); } } diff --git a/app/client/src/sagas/GitSyncSagas.ts b/app/client/src/sagas/GitSyncSagas.ts index 2bc7d7a820..efdda1ed83 100644 --- a/app/client/src/sagas/GitSyncSagas.ts +++ b/app/client/src/sagas/GitSyncSagas.ts @@ -930,7 +930,8 @@ function* discardChanges() { let response: ApiResponse; try { const appId: string = yield select(getCurrentApplicationId); - response = yield GitSyncAPI.discardChanges(appId); + const doPull = true; + response = yield GitSyncAPI.discardChanges(appId, doPull); const isValidResponse: boolean = yield validateResponse( response, false, diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/GitControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/GitControllerCE.java index 06ef5d3def..a04c67dbc0 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/GitControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/GitControllerCE.java @@ -253,9 +253,10 @@ public class GitControllerCE { @JsonView(Views.Public.class) @PutMapping("/discard/app/{defaultApplicationId}") public Mono> discardChanges(@PathVariable String defaultApplicationId, + @RequestParam(required = false, defaultValue = "true") Boolean doPull, @RequestHeader(name = FieldName.BRANCH_NAME) String branchName) { log.debug("Going to discard changes for branch {} with defaultApplicationId {}", branchName, defaultApplicationId); - return service.discardChanges(defaultApplicationId, branchName) + return service.discardChanges(defaultApplicationId, branchName, doPull) .map(result -> new ResponseDTO<>((HttpStatus.OK.value()), result, null)); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCE.java index 1ad4606217..01868109d7 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCE.java @@ -8,14 +8,15 @@ import com.appsmith.server.domains.Application; import com.appsmith.server.domains.GitApplicationMetadata; import com.appsmith.server.domains.GitAuth; import com.appsmith.server.domains.GitProfile; -import com.appsmith.server.dtos.ApplicationImportDTO; import com.appsmith.server.dtos.GitCommitDTO; import com.appsmith.server.dtos.GitConnectDTO; +import com.appsmith.server.dtos.ApplicationImportDTO; import com.appsmith.server.dtos.GitDocsDTO; import com.appsmith.server.dtos.GitMergeDTO; import com.appsmith.server.dtos.GitPullDTO; import reactor.core.publisher.Mono; +import java.util.EnumSet; import java.util.List; import java.util.Map; @@ -69,7 +70,7 @@ public interface GitServiceCE { Mono deleteBranch(String defaultApplicationId, String branchName); - Mono discardChanges(String defaultApplicationId, String branchName); + Mono discardChanges(String defaultApplicationId, String branchName, Boolean doPull); Mono> getGitDocUrls(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCEImpl.java index 4051864eb9..eaf80cc6ac 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/GitServiceCEImpl.java @@ -83,6 +83,7 @@ import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.time.Duration; +import java.util.ArrayList; import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; @@ -2189,7 +2190,7 @@ public class GitServiceCEImpl implements GitServiceCE { } @Override - public Mono discardChanges(String defaultApplicationId, String branchName) { + public Mono discardChanges(String defaultApplicationId, String branchName, Boolean doPull) { if (StringUtils.isEmptyOrNull(defaultApplicationId)) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.APPLICATION_ID)); @@ -2200,33 +2201,42 @@ public class GitServiceCEImpl implements GitServiceCE { Mono defaultApplicationMono = this.getApplicationById(defaultApplicationId); Mono discardChangeMono; - - // Rehydrate the application from local file system - discardChangeMono = branchedApplicationMono - // Add file lock before proceeding with the git operation - .flatMap(application -> addFileLock(defaultApplicationId).thenReturn(application)) - .flatMap(branchedApplication -> { - GitApplicationMetadata gitData = branchedApplication.getGitApplicationMetadata(); - if (gitData == null || StringUtils.isEmptyOrNull(gitData.getDefaultApplicationId())) { - return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); - } - Path repoSuffix = Paths.get(branchedApplication.getWorkspaceId(), gitData.getDefaultApplicationId(), gitData.getRepoName()); - return gitExecutor.checkoutToBranch(repoSuffix, branchName) - .then(fileUtils.reconstructApplicationJsonFromGitRepo( - branchedApplication.getWorkspaceId(), - branchedApplication.getGitApplicationMetadata().getDefaultApplicationId(), - branchedApplication.getGitApplicationMetadata().getRepoName(), - branchName) - ) - .flatMap(applicationJson -> - importExportApplicationService - .importApplicationInWorkspace(branchedApplication.getWorkspaceId(), applicationJson, branchedApplication.getId(), branchName) - ); - }) - .flatMap(application -> releaseFileLock(defaultApplicationId) - .then(this.addAnalyticsForGitOperation(AnalyticsEvents.GIT_DISCARD_CHANGES.getEventName(), application, null))) - .map(responseUtils::updateApplicationWithDefaultResources); - + if (Boolean.TRUE.equals(doPull)) { + discardChangeMono = defaultApplicationMono + // Add file lock before proceeding with the git operation + .flatMap(application -> addFileLock(defaultApplicationId).thenReturn(application)) + .flatMap(defaultApplication -> this.pullAndRehydrateApplication(defaultApplication, branchName)) + .map(GitPullDTO::getApplication) + .flatMap(application -> releaseFileLock(defaultApplicationId) + .then(this.addAnalyticsForGitOperation(AnalyticsEvents.GIT_DISCARD_CHANGES.getEventName(), application, null))) + .map(responseUtils::updateApplicationWithDefaultResources); + } else { + // Rehydrate the application from local file system + discardChangeMono = branchedApplicationMono + // Add file lock before proceeding with the git operation + .flatMap(application -> addFileLock(defaultApplicationId).thenReturn(application)) + .flatMap(branchedApplication -> { + GitApplicationMetadata gitData = branchedApplication.getGitApplicationMetadata(); + if (gitData == null || StringUtils.isEmptyOrNull(gitData.getDefaultApplicationId())) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); + } + Path repoSuffix = Paths.get(branchedApplication.getWorkspaceId(), gitData.getDefaultApplicationId(), gitData.getRepoName()); + return gitExecutor.checkoutToBranch(repoSuffix, branchName) + .then(fileUtils.reconstructApplicationJsonFromGitRepo( + branchedApplication.getWorkspaceId(), + branchedApplication.getGitApplicationMetadata().getDefaultApplicationId(), + branchedApplication.getGitApplicationMetadata().getRepoName(), + branchName) + ) + .flatMap(applicationJson -> + importExportApplicationService + .importApplicationInWorkspace(branchedApplication.getWorkspaceId(), applicationJson, branchedApplication.getId(), branchName) + ); + }) + .flatMap(application -> releaseFileLock(defaultApplicationId) + .then(this.addAnalyticsForGitOperation(AnalyticsEvents.GIT_DISCARD_CHANGES.getEventName(), application, null))) + .map(responseUtils::updateApplicationWithDefaultResources); + } return Mono.create(sink -> discardChangeMono .subscribe(sink::success, sink::error, null, sink.currentContext()) diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/GitServiceTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/GitServiceTest.java index 99674c9276..e587097d52 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/GitServiceTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/GitServiceTest.java @@ -12,9 +12,9 @@ import com.appsmith.external.models.DatasourceStorage; import com.appsmith.external.models.DatasourceStorageDTO; import com.appsmith.external.models.DefaultResources; import com.appsmith.external.models.JSValue; -import com.appsmith.external.models.PluginType; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.ActionCollection; +import com.appsmith.external.models.PluginType; import com.appsmith.server.domains.Application; import com.appsmith.server.domains.ApplicationDetail; import com.appsmith.server.domains.ApplicationPage; @@ -62,6 +62,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mockito; +import org.mockito.internal.stubbing.answers.AnswersWithDelay; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -3162,7 +3165,7 @@ public class GitServiceTest { Mockito.when(gitExecutor.resetToLastCommit(Mockito.any(Path.class), Mockito.anyString())) .thenReturn(Mono.just(true)); - Mono applicationMono = gitService.discardChanges(application.getId(), application.getGitApplicationMetadata().getBranchName()); + Mono applicationMono = gitService.discardChanges(application.getId(), application.getGitApplicationMetadata().getBranchName(), true); StepVerifier .create(applicationMono) @@ -3202,7 +3205,7 @@ public class GitServiceTest { .thenReturn(Mono.just("fetched")); gitService - .discardChanges(application.getId(), application.getGitApplicationMetadata().getBranchName()) + .discardChanges(application.getId(), application.getGitApplicationMetadata().getBranchName(), true) .timeout(Duration.ofNanos(100)) .subscribe();