Hi, we have upgraded from spring cloud config server 1.3.1 to 2.1.0 and we have experienced issue with hard resetting even forcePull is false. We are running config server on local machines for development purposes and we change config files during development, but since every request on config service calls JGitEnvironmentRepository.tryMerge and it calls hardReset if working tree is not clean. In older version there was no merge of remote at all. I think if there is forcePull=false, there should be no merge if local tree is dirty.
Comment From: ryanjbaxter
So are you expecting/wanting an error to occur when the local repo is dirty?
Comment From: mdoskoc
No, I would expect to skip merging remote. I'm thinking about this feature more, this scenario only applies when you run config server in development environment, because it's only time when you want to allow dirty working tree. But still forcePull property doesn't work, since it is hard reset, even forcePull is false. I will probably write my own environemnt repository and override JGitEnvironmentRepository.refresh()
Comment From: spencergibb
care to share what you wrote?
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.
Comment From: mdoskoc
care to share what you wrote?
Since we have config service running locally with repositories with file:/// any change in local config was reset with any remote change. I have create own EnvironmetRepository, and I've switched tryMerge with tryRebase, like this. I prefer rebase over merge if possible. :)
/**
* Original tryMerge was change to rebase. I prefer rebase over merge - it looks better and it's easier to work with. New functionality is that if there is any local change, it will by committed and then rebased onto origin.
*
* @param git
* @param label
*/
private void tryRebase(final Git git, final String label) {
try {
if (isBranch(git, label)) {
if (!isClean(git, label)) {
if (isDevelopmentProfileActive()) {
final boolean cleanWorkingTree = git.status().call().isClean();
if (!cleanWorkingTree) {
this.logger.warn("The local repository has uncommitted changes. Commiting changes.");
final boolean successCommit = commitLocalChanges(git);
if (!successCommit) {
this.logger.warn("Failed to commit local changes, Skip rebase to origin.");
return;
}
}
} else {
this.logger.warn("The local repository is dirty or ahead of origin. Resetting" + " it to origin/" + label + ".");
resetHard(git, label, LOCAL_BRANCH_REF_PREFIX + label);
}
}
rebase(git, label);
}
} catch (
final GitAPIException e) {
throw new NoSuchRepositoryException("Cannot clone or checkout repository: " + getUri(), e);
}
}
private boolean isDevelopmentProfileActive() {
final String[] activeProfiles = getEnvironment().getActiveProfiles();
return Arrays.asList(activeProfiles).contains("development");
}
private boolean commitLocalChanges(final Git git) {
try {
git.add().addFilepattern(".").call();
final Repository repository = git.getRepository();
final Ref head = repository.exactRef(repository.getFullBranch());
final boolean isLastInProgress;
try (final RevWalk walk = new RevWalk(repository)) {
final RevCommit lastCommit = walk.parseCommit(head.getObjectId());
isLastInProgress = lastCommit.getFullMessage().startsWith("==inprogress commit==");
walk.dispose();
}
final CommitCommand commit = git.commit();
commit.setAmend(isLastInProgress);
commit.setMessage("==inprogress commit==");
commit.call();
} catch (final GitAPIException | IOException e) {
e.printStackTrace();
return false;
}
return true;
}
This is really specific to our project, that we have config service running locally and have that config service mapped directly to configs which we work with during development, so any locally running microservice works with locally modified configs and with last remote changes. Still that hard reset is still confusing, I would rather prefer to log warining "Dirty working tree", or so. I wonder how other projects handle this scenario.