Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: how to revert after a merge conflict corruption

Tags:

git

merge

OK, as a SVN and CVS expert of 20 years, I am finding git very challenging. I have read lots of guides, not found one which is comprehensible. Many apologies for my stupidity with git.

We only use master, no branches. Git was forced on us.

I have a js file which I "own" noone else should be touching it. But someone did, and checked it in. I tried to checkin my copy, and fails. So I pull the updated version, which "corrupts" my copy with a lot of <<< and >>> entries.

Basically, I wanted to reject all his changes, and overwrite them with mine. with SVN, I would simply make a copy of my local js file, delete it, checkout from the repo to get the offending one, copy my copy back, then check the result in. Really simple.

I haven't found a way to do this in git, as if you delete the file, it thinks you want to delete it.

So I tried editing the merged file, but got mixed up which lines are the new and which the old. So now the file is unusable. i have "lost" my local copy.

I read about this: "git push origin master --force" but:

  1. its too late, I've already lost my version.
  2. i read another post which says never do this as it breaks people's pulls, but they don't offer an alternative "correct" way reject someones checkin,, and replace one file with your own.

So I assume I have to go back to a previous local commit to recover that one file. The only way I can find to do this is "git checkout [revision] .". But if I do that, I'm not on master any more, and don't know how to get back to it. Also, I expect it wont let me, because I edited and saved the problem file so it wont let me checkout a prev. version. I assume I would have to commit the broken file, then try and go back two commits, backup the file, then in a new directory checkout master again, overwrite the file, then check this in.

So I have two problems:

  1. how to get my file back.
  2. once I have it back, how do I overwrite the file someone else checked in with my own, without affecting the other stuff they checked in & pushed?
like image 252
John Little Avatar asked Mar 21 '14 17:03

John Little


2 Answers

Your two problems can be solved in the same way:

git checkout HEAD my/filename.js

Where HEAD is literal (git shorthand for current branch name) and my/filename.js should be replaced by the actual filename of your file. This will restore your file to how it was before the update, effectively "undoing" the changes from the other person. Commit this result locally and then push as normal (no --force should be necessary if you when you have updated from the central repo)

In general, the way to resolve a merge conflict is to edit your file until it's the way you want it, and then run git add. The reason git (and svn for that matter) leave the "<<<" and ">>>" results in your file after a failed merge or update is to help you or your tools to resolve the merge. Setting up a tool to help you do this will probably be worth it, but it's a shame it doesn't come out of the box.

By the way, your initial instinct from SVN to replace the unwanted file with your known good one would work just fine with one additional step: after deleting the file, restoring the good one and running git add my/filename.js. In this case checkout will also add it to the index (double-check with a git status), so you can immediately commit (locally) and then push the (now resolved) merge conflict back to the central repository.

like image 142
user3033893 Avatar answered Oct 06 '22 00:10

user3033893


You probably just want to revert the other persons commit. It is important with git that you don't run a pull if you have uncommitted local changes. If you do you can end with a merge that is very difficult to back out of.

git merge --abort

will abort the merge you have started by pulling others changes into your code. This may recover the unchecked in changes you had before you started the pull. If you have large changes in the file then take a backup somewhere else and hand merge them afterwards if it doesn't work.

run

git log --stat

and find the commit which changed your file. run

git revert <commit id>

where is the id of then commit changing your file. This will make a commit which rolls the other's commit back, push that change. If the other person had other things in the commit then they can rework their patch by reverting your revert and editing the commit to remove the changes in your file and then pushing the change again.

In the future never have unchecked-in changes when you pull, it causes trouble.

You could also consider a commit hook on the server which stops people other than you committing to that file in the future.

like image 29
slobobaby Avatar answered Oct 06 '22 00:10

slobobaby