Assume one file is in conflict state with git.
It means that the index contains 3 versions of the file, the previous one, the one from one branch, the one from the other branch.
I would like to checkout version 3 ("theirs") in the working directory, and stage version 2 ("ours") in the index.
Is there a painless way to do that?
Git has three main states that your files can reside in: modified, staged, and committed: Modified means that you have changed the file but have not committed it to your database yet. Staged means that you have marked a modified file in its current version to go into your next commit snapshot.
The Git index is a critical data structure in Git. It serves as the “staging area” between the files you have on your filesystem and your commit history. When you run git add , the files from your working directory are hashed and stored as objects in the index, leading them to be “staged changes”.
A save in Git is divided into two terminal commands: add and commit. The combination of these two commands gives you control of exactly what you want to be remembered in your snapshot.
One command I know for this is the git checkout -- filename . This discards changes made to that file in the working directory and replaces them with last staged version of the file.
Probably the most pain-free way is like this.
# Checkout 'their' version from the index into the working tree
git checkout --theirs file
# reset the index to the HEAD version, i.e 'our' branch
git reset HEAD file
Fiddling around with the index with the update-index
plumbing shouldn't be necessary unless you've lost your HEAD
(so to speak).
The trick is in "adding one version to the index": that would mark the file as solved (meaning no more "ours" or "theirs").
So it needs to be the last step.
Maybe something like:
git show :3:<filename> > <filename>.theirs # save the "theirs" version in a tmp file
git show :2:<filename> > <filename> # display the "ours" version in the working dir
git add <filename> # add it to the index
# (marking the conflicting file as resolved)
move <filename>.theirs <filename> # erasing the file with the "theirs" version
# in the working directory
Not exactly "painless"...
To avoid the temporary file, Jakub Narębski suggests using git update index
(a plumbing command) to manipulate directly the index.
--replace --cacheinfo <mode> <object> <path>
--cacheinfo
is used to register a file that is not in the current working directory. This is useful for minimum-checkout merging.By default, when a file path exists in the index, git update-index refuses an attempt to add
path/file
. Similarly if a filepath/file
exists, a file path cannot be added. With--replace
flag, existing entries that conflict with the entry being added are automatically removed with warning messages.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With