Assume the following:
A team of several designers (DesignerA,DesignerB,DesignerC...).
Main branch master
Two feature branches featureA
, featureB
.
In featureA:
4.1. DesignerA Modified ./fileA
.
4.2. DesignerB Modified ./fileB
.
4.3. DesignerC Modified ./fileC
.
In featureB:
5.1. DesignerA Modified ./fileA
.
5.2. DesignerB Modified ./fileB
.
5.3. DesignerC Modified ./fileC
.
DesignerC merges featureA
+ featureB
into master
:
6.1. merge featureA
to master
:
fileA
, fileB
and fileC
's changes are automatically merged.
6.2. merge featureB
to master
: fileC
's conflict resolved by DesignerC fileA
+ fileB
are conflicted but DesignerA owns fileA and DesignerB owns fileB.
My question:
How can DesignerC pass the partially merged commit and let each designer to solve his own conflicts?
say:
fileC
fileA
- to handlefileB
- to leave unresolved fileC
fileA
- to leave unresolved fileB
- to handleNOTE:
That doesn't mean you can't do it at all, but all ways that you can do it are currently rather bad. The fundamental problem is simple, and has three or more parts depending on how you count:
Users may use their working tree files, and/or additional files inserted into their working tree or anywhere else, to help out with the resolving, but fundamentally, a conflict exists because Git has modified its index such that some entry is marked "conflicted". To un-mark the entry—so that you can make a new commit, provided that this was the last conflict—you must resolve the conflict.
Hence, to make a commit that you can send to someone else so that they can resolve their part of the conflict, you must first resolve all parts of the conflict. Now you can commit and send the commit and they can... uhhhmmmm... undo your resolution of their parts of the conflict? Except, there's no conflict left.
Unfortunately, you can't commit a conflict. But all the tools exist within the Git ecosystem. Conflicts exist because Git's index has non-zero-stage index entries. The user's working tree also has tracked and/or untracked files that may represent partial resolutions. If we could just take each of these—the non-zero-stage entries, and the tracked and untracked files—and make commits out of them and then use those commits to re-assemble the conflicted index and work-tree contents later, we'd have the makings of exactly what you want.
The git ls-files --stage
output shows everything that is actually in Git's index. We just need to write a program that takes this output and creates multiple separate temporary indices (that, each, aren't conflicted but allow another program to build a new conflicted index later) and commits those, along with another commit or two to save the work-tree state. This mass of commits—however many are needed to save the stage 0, 1, 2, and 3 entries 1 plus the work-tree state—would probably be best represented as a faked-up merge, a la git stash
, and then indexed via some reference for temporarily resolved states that can be restored to resume merging later, a la refs/stash
for git stash
.
The similarities to git stash
are clear enough, and the implementation would likely borrow from the old git stash
shell script to some extent. The exact format for these commits, and the ref or refs to use, will require some thought and experimentation.
This command does not exist today.
1 In theory, when there are conflicted entries at stage 1 in the index for instance, there could be more than one file with some specific name, such as path/to/file.ext
. This would represent multiple merge bases. In practice Git doesn't seem to make use of this, and if it did, it is not clear how one would know which version of path/to/file.ext
went with which merge base: would every file that has a stage-1 entry have to have N such entries, where N is the number of merge bases? What hash value would go in the index slot if, say, merge base #1 has no file named path/to/file.ext
, but merge base #2 does?
This all affects the design of the in-progress-merge "merge commit" we would make for handling this.
Using git alone: you can't share a conflict, the solutions I have in mind involve creating temporary branches to let each designer fix its part independently, then combine these changes together.
Other solutions:
have the three designers work on one same clone of the repo (eg: physically walk over to one's office, remotely connect to a workstation, work on a common ssh machine...)
if the amount of files is low (one file per designer as in your example?), send a copy of the "base/ours/theirs" versions of said files, and ask to send back the resolution
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.