Conflict Resolution with gCTS
If you followed the evolution of the Git-enabled CTS, you might remember that there are several use cases that gCTS would like to help with. For two of them (distributed development and feature-development and maintenance in one system), it was said that some functionality is still missing. So gCTS is not able to completely support them. With SAP S/4HANA 2020, gCTS has climbed up the lather a bit. It now offers a conflict resolution editor. Conflicts might occur if you decide to reduce your system landscape in the case of feature development and maintenance in one system.
The use case distributed development is different but might have the same demand for solving conflicts from time to time: For ABAP, there is normally no development environment available, that is used by one single developer. Teams share one ABAP runtime and develop in there. Nevertheless, if there are many developers, it might make sense to have several development systems to reduce dependencies and interferences between teams. A distributed development scenario is the consequence. But on the other hand, production systems are not distributed. Functionality developed by different teams has to be integrated at some point to make it available to business users on the production environment. It can easily happen that the same objects were touched by different teams. When integrating, these objects will come up as conflicts. Conflicts need to be solved.
Starting with SAP S/4HANA 2020, you can make use of the conflict resolution editor to solve conflicts.
But before you can start doing so, you have to set two parameters for your repository: VCS_AUTOMATIC_PULL and VCS_AUTOMATIC_PUSH. Both need to be set to ‘false’. This is to stop the default automatic pull and push behavior of gCTS when a new transport request is released: Pull the current commit from the remote repository, overwrite what was pulled with the changes that are part of the released transport request, and push the changed files (objects) to the remote repository.
More details on how to work with these parameters are available on the SAP Help Portal at Disable Automatic Pull and Push.
After you have set these parameters for your repository, you might want to know how this works. So, I will provoke a simple conflict situation, and use this example to show you how conflicts can be resolved.
For this example, I use just one development system and simulate the conflict by manually editing a file directly in the remote repository. For sure, this is not how conflicts arise in the daily life of developers, but this is in my eyes a sufficient and simple example to show how conflicts can be handled in gCTS.
I have already created a package in ABAP that uses a transport layer which is configured to push objects to Git whenever a transport request is released. For more information, see Define ABAP Packages as Managed by Git-Enabled Change and Transport System.
The commit from the transport request that I used when I created the package is displayed on the Commits tab.
- Next, I create a new class. This class creates a simple key-value-pair ‘Hello SAP’
- After releasing the transport request for the class, it is not immediately visible as a new commit on the Commits tab, because I´ve disabled the automatic push. This means a push has to be initiated manually after a transport request was released. On the Objects tab of my repository, a Push button is displayed.
I click on the Push button to manually push my changes to the remote repository.
I have to confirm a popup that I would like to push.
- In ABAP, I used a transport request with the description ‘Conflicting Class’ when I created the class. That is why there is now a new commit visible in my Commits tab that has the message ‘Conflicting Class’.
- To simulate that my class was changed and committed by another ABAP developer who works on the same class as I do but in a different ABAP runtime, I manually changed the execute method of my class directly on GitHub. The key-value pair is now changed to ‘Hello someone’.
I have committed this change.
- Back in my own ABAP development system, I decide to change the value to ‘Hello there’.
- When I activate (save) that, I need to create a new transport request. To reflect in the commit message what I have done, I enter ‘Hello there’ as Request Description.
- I am done with my changes; I release the transport request.
The expectation is now that a conflict comes up as someone changed the class to ‘Hello someone’. This is the version of the coding on GitHub in the remote repository. I changed the class to ‘Hello there’ – but the version that I started from when doing this change was ‘Hello SAP’. So, I did not take that latest state of ‘Hello someone’ into consideration when changing the class. This is why a conflict is now to be solved. Should it be ‘Hello someone’? Should it be ‘Hello there’ or some merge between the two? This is what we now have to resolve. And we are going to use the mechanisms that gCTS offers in SAP S/4HANA 2020 SP1 to do so.
- Open the Commits tab in the gCTS app
Note that the Current Commit in the header is not identical to the latest commit in the list of commits. This is because the current commit in the header points to the latest commit on the local repository. The list of commits, however, displays the commits on the remote repository. And this is also why there is no commit written in bold any more in the list: No commit from the remote repository is currently active locally.
At first, I have to make gCTS on our ABAP development system aware that there is a change on the remote repository – remember, we disabled the automatic pull from the remote repository.
Click on Update to Latest Commit on the Commits tab.
- A message is shown that the commit from remote could not be pulled –due to the conflict, the update to the latest commit is not possible. Click OK
When I switch to the Log tab, I find an entry in red that the push could not be executed. If I look into the details, I see that there is a merge conflict.
- I switch to the Objects tab. The ‘Push’ button indicates that there is one commit to be pushed – but it is inactive. Pushing is currently not possible as there is one unresolved conflict. This is the entry shown in the Conflicting Files section. The item in there is the method that we changed twice – on GitHub and in our ABAP development environment.
I click on the file name.
- This brings up the conflict resolution editor. I can see the local version of my method as it is currently available in the ABAP runtime. This version does not necessarily have to be part of a released transport request. The idea here is that you can see the current state of an object as it is currently used in our development system as this is most probably the basis of coding that you know and how you expect your functionality to work. On the right side, I can see the remote version of the method (that is available in GitHub), and a merged version with markers for the conflicts in between.
- The content in the Merged Version panel can be edited.
When I click on the conflicts, I get a popup with some options to decide what to do to solve the conflicts.
I want to change the value to ‘Hello Everyone’. To do so. I remove the duplicate coding, and the conflict markers. In addition, I change the value to ‘Everyone’. Note that there is no code checking involved that makes sure that your ABAP coding is syntactically correct. Afterwards, I choose Mark As Resolved.
- I have to confirm that I would like to save the conflict resolution and add the file to the index of the local repository to stage my merged file.
- After staging, I can now commit the changed file. The file shows up in the section Local Files as Tracked File.
- I confirm that I would like to commit the merged file to the local repository.
- I can see that the number of the current commit in the header changed – the new commit is now available on the local repository.
- To add this commit to the remote repository, you have to push it.
For this, the Push button now became active in the Local Files section on the Objects tab. Note that it shows ‘2’ in brackets. This means that two commits will be pushed: the commit from the released transport request that contains the text ‘Hello there’ and the commit from the conflict resolution that contains the text ‘Hello everyone’.
Note that I cannot decide which commits I would like to push. There´s also no possibility to see the commits that will be pushed. I always have to push all local commits.
- I confirm that I would like to push the local commits to the remote repository.
- If I now switch to the Commits tab, I can see that a new commit Generated commit is shown and is active. The commit message would be more meaningful if I had entered something as Commit Message in the previous step before I executed the commit. The previous commit is the Hello there one that I created initially to provoke the conflict. So, these are the two commits that where pushed when I used the manual Push in the previous step.
Note that Generated commit is now the latest commit and it is written in bold. But the coding that I created while merging is nevertheless not the active coding in the ABAP runtime of my development system. To get it active, I can do one of the following:
a) Activate the previous commit (and thereby deploy this coding to my development system) and then activate the latest commit again
b) Manually redo my changes on the development system. Afterwards, I have to Push the latest commit manually on the Objects tab again – this time without having to solve any conflicts.
c) Set up a pipeline that also deploys new commits to the development system
I hope that this simple example showed the idea of how conflict resolution can be done when gCTS is in use. Try it out for yourself and let me know if you have questions
You can find more details on the SAP Help Portal at Use the Objects Tab of a Repository. and Resolve Conflicts.
The complete documentation for Git-enabled CTS is available on the SAP Help Portal at Using Git-Enabled Change and Transport System.
If conflicts occur during development it is, in my opinion due to bad architecture or planning and split of change requests, if changes are needed it a central place it seems like a https://en.wikipedia.org/wiki/God_object.
With ~4500 commits in abapGit over the last 6 years, we rarely see conflicts, conflict resolution is a rarely used functionality, typically not used in the daily work. Conflicts is a natural result of bad architectures, and cannot be solved by any versioning mechanism, but instead must be solved via architecture and planning change requests.
In the case that a conflict occur, what is the background for adding custom functionality for conflict resolution? This is already built into GitHub, GitLab, and probably more.
thanks a lot for your comment.
I adapted the introduction to explain why and in which use cases gCTS would need support for conflict resolution.
Having the conflict resolution option inside the gCTS App allows in my eyes a simple workflow. You don't have to switch to another tool or UI to solve conflicts. You can reach the functionality from within the gCTS App. In addition, the conflict resolution editor shows in the left column the current state of the concerned object in the ABAP runtime at the point in time when you do the conflict resolution. This version of the object doesn't have to be released. With this, you can take the latest changes into consideration when resolving the conflict
So we have similar landscape, where multiple systems are now consolidated into 1 single landscape and chances of multiple developers requiring to work on same object increases. Does GitCTS help to address this issue ?
Thanks and Regards
gCTS does not change the locking mechanisms that the workbench provides. An object is still added to a task and locked for editing by others until the task is released.