2

Background

In the repository I'm working on,

There's a main branch master and a protected development branch stage.

We developers send all our MRs to stage and the admin updates master with stage when its the right time.

What I did

So I was on my branch, let's call it changesA. I have been working on it since 2 days, during which the stage branch had been updated after merging some branches.

Today, after updating my remote branch with my changes, I take a pull from stage -

git pull origin stage

There were a few merge conflicts, let's say in 10 files. I resolved them and pushed the changes. So now my remote branch is updated with stage. A new merge commit was created in my commit history with 152 changed files (1587 additions and 4543 deletions).

I realised that I made some mistakes while resolving those conflicts. So I reverted my merge commit using this method. A new revert commit was added to my commit history with 152 changed files (4543 additions and 1587 deletions).

I worked more on my branch and updated my remote branch with the changes.

What's the problem

At this point, I expect my branch to be behind stage since I reverted my pull. And I expect there to be conflicts in those 10 files that I basically unresolved when I reverted the merge commit.

But when I run the same command git pull origin stage, it says that my branch is already up to date with stage. I believe for some reason, my branch has been marked as resolved and updated with stage.

What went wrong here and how can I resolve those same 10 conflicts?

What I've tried (that didn't work)

  1. I tried checked out to stage and updated my local stage.
  2. git fetch on my branch.
  3. I created a copy of my branch by git checkout -b changesACopy and tried git pull origin stage. Got the same message.
  4. I deleted all my local branches, checked out stage and took a pull. Then checked out my branch and took a pull.
  5. I checked out a branch from stage and created a change to one file that will create a merge conflict with my branch. Merged that branch to stage. I expect there to be 11 files with merge conflicts with my branch, but there was just one.

What worked

Well there are no shortcuts. Here are the steps that I took to resolve this -

  1. git reset --hard HEAD~4 to the point where I pushed my changes just before pulling from stage.
  2. git pull origin stage again. This time I get to resolve those 10 conflicts again. (I did it right this time!)
  3. git cherry-pick <commit-hash> of my latest changes that I pushed after reverting.
  4. git push origin changesA --force. Force was needed because I went back in history, so my local branch is behind my remote and git would reject any push before pulling. I was working on my branch alone so I knew that I won't be overwriting any changes if I force push.

DONE!

Thanks for all the help. I knew this course of action but I wished to know why revert didn't work like I expected it to. The accepted answer covers that.

Aakash Choubey
  • 426
  • 3
  • 19
  • git revert is a git commit with reverse changes of the commit made. In git conventions this is moving forward. You dont have to worry about `git pull origin stage` showing already up to date, because it is up to date with changes in stage branch. All commits in stage branch are already on your branch. What you should check is what happens when you create PR from changesA to stage. If that shows correct changes then you should be good. – Vishwanath Dec 24 '19 at 13:02
  • I checked a few of the files and my branch does not have the changes from stage. When I create a PR, it assumes my branch to be the truth and overwrites those 152 files. – Aakash Choubey Dec 24 '19 at 13:06
  • 2
    Simplest way: create a new branch from `stage` and `cherry-pick` commits from your branch into this new branch and fix any conflicts that appear again. – Saravana Dec 24 '19 at 13:08
  • 1
    Or go back to commit before you merged stage in your branch by doing `git reset --hard ` and then do the merge again. Make sure you keep the current commit as a branch so you can come back to it again if needed. – Vishwanath Dec 24 '19 at 13:10
  • 1
    Note that there is no such thing as a resolved or unresolved *branch*. A *branch name* just identifies some commit. A commit either exists (and then can be identified by hash name), or doesn't. That's it—that is all there is to a branch in Git! (Well, almost all. :-) ) – torek Dec 24 '19 at 20:04

1 Answers1

2

But when I run the same command git pull origin stage, it says that my branch is already up to date with stage.

Sure: stage was already merged before to branchA.
Ant change (revert commits, fixes, ...) done one branchA after the last merge won't be impacted by a new merge from stage to branchA.

  --s--s (stage)
        \  <= merge already done 
 --a--a--M--[revert]--[fixes]

If you are alone working on branchA, the best practice would be to rebase branchA on top of stage whenever you want to integrate stage, force push branchA, and later do a merge from branchA to stage (trivial fast-forward merge)

In your case, it would be easier to reset branchA to before the merge, rebase and resolve the same conflict, then force push.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250