I have been examining the work on merge tracking with an eye towards
implementing the API's to make a user-friendly merge GUI, most likely built
on top of Subclipse. I have also been consulting with Daniel Rall about a
lot of this and he has helped clarify how things work. The goal I have is
be to build some kind of merge GUI tool that is at least as good as how we
know some of the commercial tools likes ClearCase handle the merge process.
In thinking through how a UI would work based on the API's that are planned
and available, I have some real concerns I wanted to raise with the list. In
the end, I am not sure there will be anything we can do about some of these
things, but raising them and talking about them cannot hurt.
Anyway, enough beating about the bush. I am going to spend a few paragraphs
describing how merge tracking currently is planned to work. This is mainly
just to confirm that I understand things correctly, I am sure it will help
some others understand as well. I will then state the problems I see and
offer my "drive by" solution.
Background
With the merge tracking feature in Subversion, we now get into situations
where in order to complete a merge operation that the user requested,
Subversion might essentially wind up running several merge operations. For
example, the user might be working on a feature branch that they want to
synch with trunk or some other branch. The user might have already
cherry-picked certain revisions from trunk, so in order to synch up the
branch, the merge process will internally have to make several passes to
merge all of the revision ranges. In other words, the merge tracking
feature is automating what the user could conceivably do today, which is
perform several merge commands for all of the needed ranges.
Problem to Solve
In the above scenario, when each pass of the merge runs it is possible that
one or more conflicts are created from the merge. If any conflicts are
created, then merge can finish the current pass it is performing, but it
cannot continue on to do the next pass unless those conflicts are resolved.
Proposed Solutions
There are really two proposed solutions to this problem currently:
1. abort the merge at the end of the pass
2. use callbacks to resolve the conflicts.
The first solution is the one currently planned for the command line. The
merge command will end when it completes a pass that contains conflicts. The
user will be expected to resolve the conflicts and then run the merge again
so that it can continue with the next pass. The user could potentially have
to repeat this process many times.
The second solution has been viewed as the one that graphical tools would
adopt. At the end of a merge pass with conflicts, the merge operation would
have to issue callbacks, one at a time, for each of the files in conflict. The
GUI tool would supply some kind of graphical tool for resolving the
conflicts in the file and then return with an indication of whether the user
resolved it or not. This process would repeat for each file in conflict. When
the final file was finished, if all conflicts were resolved, then the merge
operation would pick up at the end of the pass and continue the merge
process. This conflict resolution stage would potentially repeat after each
pass, depending on whether there were conflicts.
Problems with this Approach
Up to this point, I have really just been summarizing the current plans. In
part just to make sure I am accurate in my understanding of how things will
work, but also to set the stage for stating what I see as the problems. It
basically comes down to usability. I do not think either of these options
provides a very usable solution for the user. The only exception, perhaps,
would be if we see this situation as somewhat rare. For example, the
problem only exists when merge has to do multiple passes, and then only when
there are conflicts. Also, the time to complete each pass would be a factor
in the overall usability.
Of the two solutions, I think I prefer the first one for usability because
it offers the best environment for resolving the conflicts. But in general
it still sucks. The user needs to potentially run the process many, many
times to finish the merge. If we adopted this approach as our likely path,
then I think we would want some kind of information or callback when the
merge aborts where we could provide the user a reasonable explanation of
what we have merged so far and what they need to do to continue. That would
help usability somewhat.
I think I hate the second solution. First, I think that resolving conflicts
might be too difficult to handle in a serialized process. We are
essentially talking about launching a conflict resolution editor, likely in
a modal dialog of some sort so that we know when they are finished. This
could make it hard or impossible for the user to examine related files, and
it also is just a very awkward UI model. If the user does not know what to
do they have to bail out of the process, and could even do so accidentally
fairly easily. Of course you could argue that makes this option no worse
than the first option. I just think the notion of a long running process
somewhat randomly throwing dialogs at you would not make for a good
experience. Consider, the merge process could easily run for 10 or more
minutes, then ask you to resolve some conflicts, then run for 10 or more
minutes and ask you to resolve some more, then run for 20 more minutes, etc.
Another awkward aspect of this process is that you might be asked to resolve
conflicts in the same file several times during the process. I think if we
adopted this approach for our UI, we would need some kind of additional
information in the callback that we could give to the user. Perhaps the
range of revisions being merged into the file at the moment? I guess just
something that would help the user gauge the progress and/or distinguish
between several calls to resolve conflicts for the same file. Otherwise,
they might think they are in a loop and not really appreciate that they are
making progress.
Finally, in either solution, an inconvenience exists that a user could be
resolving conflicts in areas of code that are going to be removed in later
stages of the merge.
Other Solutions
So what other solutions exist? I can only think of one, and I feel like it
is just a drive-by suggestion since I do not know much about what is
involved. I am sure this was considered and ruled out because it was either
deemed too difficult or perhaps even impossible to implement. My solution
would be to perform the merge in one pass. Somehow, we would have to
collapse all of the revisions being merged into something that can be
expressed as a single diff. I am just hand waving at this point because, at
the technical level of how merges are implemented, it is all way over my
head. If the merge process could be done this way, I do think it would
resolve all of the problems I can think of and we would be able to present
the user with a good experience. Basically, it would work like merge does
today, only better because of the merge tracking automation. The user would
run merge, some conflicts might be generated, and they would be resolved by
the user after the merge completes just as they do today. If this feature
could be implemented, it would suggest a diff analogue could be created and
that would potentially help us in providing the user with a good merge
preview, which is another aspect of the UI I want to write.
Conclusion
I am not harboring any great hope that my suggested solution could be
implemented. I just figure I need to raise these issues sooner rather than
later. There are a lot of smart people on this list and some of you may see
workable solutions to the problems. Likewise, I am sure there are many of
you that are more familiar with what the competition does than I am, and
perhaps their tools suffer many of these same usability problems. As it
stands though, I do not see any possibilities for solving the core usability
problems in a GUI tool alone. We can figure out the areas where it is not
ideal and perhaps do things to make it suck less, but I do not think we can
deliver something to the level of some of our competition without the
support coming from Subversion.
--
Thanks
Mark Phippard
http://markphip.blogspot.com/
Received on Tue Mar 6 14:55:45 2007