Resolving merge conflict like gitlog

Answered

Hello,
I'm trying to develop a plugin where I want to update a branch with remote branch.
My idea goes like this:

  1. For current working branch, it fetches the remote changes
  2. Then tries to merge the changes with the local working branch

Now, this can get a bit problematic when your local uncommitted changes get conflicted with remote changes. The way intellij handles this in its default gitlog tool is: it prompts user with a dialog and allows user to resolve the conflict nicely! And this is what I want to do when it happens with my plugin mergeing remote changes!

This is what shown by IDE when conflict happens:


Now below is what I have been able to achieve so far:
I have mentioned lines of code which are necessary to understand my implementaion.

GitRepositoryManager man = GitRepositoryManager.getInstance(project);

// assuming only one repo for the project
GitRepository repo = man.getRepositories().get(0); 
GitLocalBranch cb = repo.getCurrentBranch();
Git gitInstance = Git.getInstance();

/*
 * Fetch the branch changes
 */
GitLineHandler lineHandler = new GitLineHandler(project, repo.getRoot(), GitCommand.FETCH);
lineHandler.addParameters("origin");
lineHandler.addParameters(cb.getName());
GitCommandResult result = gitInstance.runCommand(lineHandler);

if (result.success()) {
	/*
	 * Now merge the changes!
	 */
	GitLineHandler mergeHandler = new GitLineHandler(project, repo.getRoot(), GitCommand.MERGE);
	mergeHandler.addParameters("origin/" + cb.getName());
	GitCommandResult mergeResult = gitInstance.runCommand(mergeHandler);

	// Conflict detected!
	if (!mergeResult.success()) {
		/*
		 * Hoping, IDE will prompt user to resolve the conflict manually here!!!
		 */
		GitConflictResolver.Params params = new GitConflictResolver.Params(project);
		params.setErrorNotificationTitle("Merge conflicts");
		
		List<VirtualFile> roots = List.of(repo.getRoot());
		GitConflictResolver resolver = new GitConflictResolver(project, roots, params);
		
		if (resolver.merge()) {
			// Conflict has been resolved manually, now notify the IDE about the changes!
			man.updateRepository(repo.getRoot());
		} else {
			System.out.println("Merge resolve was aborted!");
		}
	}
} else {
  	System.out.println("Fetch failed");
}

With above implmentation, I have been able to fetch changes, and get it to start merging. For any non-conflict scenario, merge happens just fine. However, when merge conflict happens, it fails to show a dialog as shown above and obvious error message is logged in the console:

“[error: Your local changes to the following files would be overwritten by merge:,     test, Please commit your changes or stash them before you merge., Aborting]

So, my question is: “What am I doing wrong? or Is is even doable with current SDK capabilites?” If so, could you please tell how to do it with a concrete example. I have tried many things: searching google, using ChatGPT, JetBrains AI etc. but couldn't find anything helpful.

At the end, what I will precisely need is to do is to know if user had decided to abort the merge conflict resovle after suggested by IDE  or all went ok as a callback so that I can do other tasks.

0
3 comments

Hi Abdul,

Looking at the usages of GitConflictResolver in https://github.com/JetBrains/intellij-community, it seems you need to somehow handle the case when the user resolves all conflicts (rebase or create a merge commit), so implement the git4idea.merge.GitConflictResolver#proceedAfterAllMerged method:
https://github.com/JetBrains/intellij-community/blob/master/plugins/git4idea/src/git4idea/actions/GitMergeAction.java#L180-L188

or use one of the subclasses of GitConflictResolver, which implements it (e.g., GitMergeCommittingConflictResolver).

1

I maybe misunderstand something, but why do you need all of this?

The code only does git fetch origin followed by git merge origin currentbranchname. It is exactly what Update project does, and the conflicts are already handled there.

1

First of all I really appreciate you considered time replying to this.

 

I actually don't want to replace built in gitlog plugin provided by jetbrains. This is just a feature that I would like to have for my plugin which will make it more efficient and all related options are in one place! Most importantly my plugin behaves more natural to users .

 

Yes, you guessed it right. I want to update current working branch with remote. So I first fetch the remote change and then merge it in current working branch. However, if the remote changes override, uncommitted local changes then git merge should popup with a dialog to ask user to resolve manually. But my code doesn't popup with that dialog I showed in the post. And it just overrides uncommited local changes silently which is very scary 😨

 

I am currently trying to resolve this by following Karol's suggestion but haven't got any luck yet. To me it sounds more involved than what I thought.

0

Please sign in to leave a comment.