I have two files committed in a git repository, an original
file and a derived
file.
derived
is based on original
but has some modifications (i.e., diff original derived
produces some small output).
Whenever I modify the original
file, I also want to apply the same changes to derived
semi-automatically via a script. There is a useful git command for that called git merge-file
that allows me to do exactly that.
I my case I want to apply the changes of original
in the index (i.e., original
is modified but not committed yet) to the derived
file so I do something like this:
git cat-file -p HEAD:original >orignal.base
git merge-file derived original.base original
rm -f original.base
Now derived
should have the same changes that were applied to original
(and diff original derived
should be more-or-less unchanged).
However, there is a chance that a merge conflict occurs, in which case git-merge-file returns a non-zero value, and leaves the output file (derived
) with merge-conflict markers (<<<<<<<
, =======
and >>>>>>>
). This is where my question comes in.
What I want to do, is that in case of a merge conflict instead of having derived
be marked as 'modified' in the index, I want it to appear as 'both modified' like when a merge conflict occurs (less like with git merge
, more like with git stash apply
).
I have looked through all the available git commands, and there are some like git read-tree -m
which does almost what I want, but for trees and not for blobs.
So my idea was to use something like git update-index
. Reading a bit on how the git index works, like in this question, files in the index have a so called 'stage entries', which is usually 0, e.g. for the above files we would have
$ git ls-files --stage
100644 cd2732a3aeeb97c20b5dc809cc6350fd7fbfb944 0 derived
100644 4b48deed3a433909bfd6b6ab3d4b91348b6af464 0 original
But after a merge conflict (for example after a failed git stash apply
it looks like this:
$ git ls-files --stage
100644 cd2732a3aeeb97c20b5dc809cc6350fd7fbfb944 1 derived
100644 68bc18a75908806fd6c9c816b7370f4797a6be15 2 derived
100644 d4cda09e1616383549548d7212cdcb86b4dda596 3 derived
100644 4b48deed3a433909bfd6b6ab3d4b91348b6af464 0 original
with 1
being the base file, 2
being the locally modified file and 3
the file from the stash. The file in the working directory contains the merge-conflict markers that are also produced by git merge-file
. But git update-index
does not support setting these 'stage values'
So what I want to do is the following, in case git merge-file
fails:
- Add the file
original.base
as1 derived
(base) - the file
original
as2 derived
('our' modification) - and the original
derived
file as3 derived
('their' modification) into the index - (keep the
derived
file with the merge-conflict markers in the worktree)
The reasons for wanting to do this are:
- It is obvious to the user that there is a merge conflict that needs to be resolved
git commit
will fail until the conflict is resolved- The user can use
git mergetool
to resolve the conflict in a GUI application, which is not possible with the normal result ofgit merge-file
Is there any way to achieve what I want to do
- Either by adding the files to the index with a non-zero 'stage entry' as described above
- Or with another simpler/better way I couldn't think of to achieve the same result
Thanks.