git / resetting merges

git / resetting merges

  • Written by
    Walter Doekes
  • Published on

Today’s git question: does git reset undo a merge or only parts of it?

TL;DR: It undoes the entire merge.

If you think about it logically, it must, since an object describes the entire state of the repository. But it can feel awkward and unexpected that older items than the object that we’re resetting to, are removed as well.

Let’s just try it. Set up a repository with two branches:

$ git init
Initialized empty Git repository in /home/walter/Junk/gittest/.git/
$ cat > document.txt << EOF
This
is
a
pretty
short
and
quite
manageable
document.
EOF
$ git add document.txt; git commit -m 'initial commit'
[master (root-commit) 3777fb9] initial commit
 1 file changed, 9 insertions(+)
 create mode 100644 document.txt

$ git checkout -b long
Switched to a new branch 'long'
$ sed -i -e 's/short/long/' document.txt
$ git commit document.txt -m 's/short/long/'
[long 6e201e1] s/short/long/
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git checkout master
Switched to branch 'master'
$ sed -i -e 's/document./bit of documentation./' document.txt
$ git commit document.txt -m 'Clarify meaning of doc'
[master 1bd94ee] Clarify meaning of doc
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git checkout long
Switched to branch 'long'
$ sed -i -e 's/long/longer/' document.txt; git commit document.txt -m 's/long/longer/'
[long 0491d3f] s/long/longer/
 1 file changed, 1 insertion(+), 1 deletion(-)

The log of long looks like this:

$ git log --pretty=oneline
4e7d24196eb624df2eed3977c61bea3efb5e1af7 s/long/longer/
6e201e1786c0997a13f3cc2842df71e6f01aae06 s/short/long/
3777fb93ec12e48abc7899066c75122926f5f1e6 initial commit

And the log of master now looks like this:

$ git checkout master
Switched to branch 'master'
$ git log --pretty=oneline
1bd94ee1c399139e8851acaefcc4bd968bd50002 Clarify meaning of doc
3777fb93ec12e48abc7899066c75122926f5f1e6 initial commit

Let’s merge long into it.

$ git merge long
Auto-merging document.txt
Merge made by the 'recursive' strategy.
 document.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git log --pretty=oneline
eea3354f4592175dbbbec321678a8bf9be9b9296 Merge branch 'long'
4e7d24196eb624df2eed3977c61bea3efb5e1af7 s/long/longer/
1bd94ee1c399139e8851acaefcc4bd968bd50002 Clarify meaning of doc
6e201e1786c0997a13f3cc2842df71e6f01aae06 s/short/long/
3777fb93ec12e48abc7899066c75122926f5f1e6 initial commit

So, the question was: when we reset to 1bd94ee (“Clarify meaning of doc”), do we keep 6e201e1 (“s/short/long/") or not?

The answer: git reset will get you out of the entire merge.

$ git reset --hard 1bd94ee1c399139e8851acaefcc4bd968bd50002
HEAD is now at 1bd94ee Clarify meaning of doc
$ git log --pretty=oneline
1bd94ee1c399139e8851acaefcc4bd968bd50002 Clarify meaning of doc
3777fb93ec12e48abc7899066c75122926f5f1e6 initial commit

Back to overview Newer post: daemon reparented / init --user Older post: apt / hold upgrades / dependencies