Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accidentally merged in wrong branch to mine. Is there a way to remove these unwanted files?

Tags:

git

merge

I accidentally merged a co-workers branch into the branch I was working on. I've made several commits since then so ideally I don't want to revert to the state the branch was before the merge. However, I haven't done anything that has altered his files.

Is there a way I can remove his branch's files from mine?

(Sorry, I am new to git - hope I've got the terminology down).

like image 681
MeltingDog Avatar asked Feb 16 '17 01:02

MeltingDog


People also ask

Which command should someone use to undo the merge who has accidentally merged the wrong branches?

The git revert command will have generated a commit that restores your branch's state to where it was before the faulty merge. If your merge was remote (i.e. happened on GitHub) you can push this commit like any other and you'll be set to go.

Can you delete branch after merging?

When you're done with a branch and it has been merged into master, delete it. A new branch can be made off of the most recent commit on the master branch. Also, while it is ok to hang onto branches after you've merged them into the master they will begin to pile up.

How do I cancel a merged branch?

How do I cancel a git merge? Use git-reset or git merge --abort to cancel a merge that had conflicts. Please note that all the changes will be reset, and this operation cannot be reverted, so make sure to commit or git-stash all your changes before you start a merge.

What happens to a branch once it has been merged into another?

When you perform a merge, you effectively merge one branch into another—typically a feature branch or bug fix branch into a main branch such as master or develop. Not only will the code changes get merged in, but also all the commits that went into the feature branch.


2 Answers

Perhaps the easiest and safest option here would be to revert the merge commit which you made a few commits ago. To do this, find the merge commit in your history using git log, and record the SHA-1 hash of that commit. Then, do the following:

git revert -m 1 <SHA-1>

Here <SHA-1> is the hash of the merge commit you want to undo. The -m 1 option tells Git to revert to the first parent, which is the branch on which the merge originated, which should be your branch.

like image 59
Tim Biegeleisen Avatar answered Oct 06 '22 11:10

Tim Biegeleisen


If you have not pushed (published) your commits anywhere, the simplest fix is to rebase the merge away. (You can do this even if you have published them, but see the caveat.)

The command git rebase copies commits, but by default, it discards merge commits. The normal goal of git rebase is to copy commits so that they come at a different point. For instance, you might have this:

...--o--*--o--o     <-- master
         \
          A--B--C   <-- yourbranch

in your repository after you pick up some new master commits from some "upstream" repository (origin), and now you'd like to make your A-B-C sequence come after the last commit on master, rather than coming after commit * (commit * is the first commit that is on both master and yourbranch).

You then git checkout yourbranch && git rebase master and Git copies the commits to new ones, A'-B'-C' (copies of the originals), and tosses your old ones:

                A'-B'-C'   <-- yourbranch
               /
...--o--*--o--o     <-- master
         \
          A--B--C   [abandoned]

But, since git rebase normally discards merges, you can rebase to where you are now, and in the process, toss out a merge:

...--o--*--o--o--o--...
         \     \
          A--B--X--C--D   <-- yourbranch

Here, your merge commit X is a mistake and you wish to get rid of it (I've drawn it as merging the mainline, but it could merge something else—it doesn't really matter what you merged, just that it is a merge commit, with two backwards-pointing arrows coming out of it, when Git looks at it). So you find the hash ID of commit * and run:

git checkout yourbranch; git rebase <hash-id>

Git lists the commits to copy as "those after *, up to the tip of yourbranch, except for any merges". That's A-B-C-D. It then "copies" A (it doesn't have to so it actually re-uses the original A by default), "copies" B (again it doesn't have to), copies C (it has to this time—the original C connects to X and the new one must connect instead to B), and copies D, making yourbranch point to the last copied commit and abandoning the old chain:

...--o--*--o--o--o--...
         \     \
          A--B--X--C--D  [abandoned]
              \
               C'-D'  <-- yourbranch

With D abandoned, all three of D, C and X simply vanish off the map entirely:

...--o--*--o--o--o--...
         \
          A--B
              \
               C'-D'  <-- yourbranch

With C and D having vanished, we don't even need the C' and D' markings. I will leave them in, though, and merely straighten out the kink we also no longer need:

...--o--*--o--o--o--...
         \
          A--B--C'-D'  <-- yourbranch

The commit message for C' looks like the one for C, and the one for D' looks like the one for D; and C' and D' are "just as good as" the originals—or, actually, even better: they're new and improved! :-) because they omit the merged stuff.

Caveat: Because these are "new and improved", they have new hash IDs. This means that if you have published them, anyone who has the old ones will still have them, and will know them by their old hash IDs. You must now convince these other Git users, with their other repositories, to take the new-and-improved copies and discard the old-and-lousy ones, just like you did.

If you haven't published these commits anywhere, no one else has the old ones, and there is nothing to worry about.


Note, by the way, that you can git rebase onto a new base, just as you would for updating to the latest master. This just copies all the commits (to the new location), instead of re-using whichever commits it can (at the old location) and copying the rest. (But you'll face any update-related issues when you do this, just as you would for any such rebase. That is, if whoever updated master, or whatever it is you are updating to, touched the same code in the same files, you will have to resolve any merge conflicts that occur. If you're only deleting a merge, and there were no merge conflicts in the merge, there won't be any in the rebase.)

like image 33
torek Avatar answered Oct 06 '22 10:10

torek