Git branch diverged

12,367

There a few ways.

Merge

First, you could simply merge origin/uitest, but that doesn't leave a clean history in that it introduces what looks like a branch and merge even though it was meant to be the same branch all along. I believe Linus liked to call these kind of merge commits "pointless". Unfortunately, this is also the easiest approach.

Rebase

Rebasing tends to be a more advanced topic and can introduce a whole host of other problems if you aren't careful. That said, it's also a great way to get clean history without the pointless commits. In this case, you could do:

git rebase origin/uitest

from you uitest branch, and it would take all the work you did, and put it on top of the work in origin/uitest.

There are a couple of catches though. First, if you've merged any other branches into your branch, git rebase will drop them. You need to pass the -p flag to keep any merge commits you introduced, but that's not always the right thing to do either. If all you did was commit your own changes, you should be fine with the command I've given about.

Second, any time you use rebase you should always remember to never rebase public commits. Rebase will change the commit ids because the parents have changed. If people are merging you work, and you rebase it, they'll end up with several copies of your commits in the history--which is badness. So be careful about when you apply this technique.

All that said, you want to make git rebase your friend. It's a powerful and useful tool, but as with any power tool, it can be dangerous.

Discard your work

If you simply want to discard what you've done, you can run:

git reset --hard @{u}

or

git reset --hard origin/uitest

That will reset your uitest branch to match the upstream or origin/uitest. It will discard your commits.

Personally, I'd rebase the work or at least give it a try. If it fails, or becomes to complicated from merge conflicts, you can always abort with git rebase --abort, and then fallback to merge or discarding your changes (although merging will likely show you the same merge conflicts).

Share:
12,367
Val
Author by

Val

Founder and director of Mount Media Ltd a web design agency in London. https://www.mountmedia.co.uk

Updated on June 04, 2022

Comments

  • Val
    Val almost 2 years

    I am new to GIT, although I understand it's concept I don't think I understand it's practice as well.

    I was given a branch, uitest to work on, because I may have not done the push, commit, pull correctly, I have now diverged the branch.

    Because I am new here, n I also don't want to override other devs codes as my code or changes are simply experimental to get used to git and how it works I wouldn't mind discarding my changes as I have a copy of everything I need to re-do everything.

    $ git status
    # On branch uitest
    # Your branch and 'origin/uitest' have diverged,
    # and have 47 and 6 different commits each, respectively.
    #
    nothing to commit (working directory clean)
    

    How would I undiverge? discard my changes and pull the most recent changes from the latest changes and then continue working without messing other peoples work.

    Also, as I am new to this, be a little descriptive about your answer as it may not make much sense to me.

    Many thanks

  • Val
    Val about 11 years
    Ok, git reset --hard origin/uitest did me justice :) thanks, Can I ask a silly question here is what I usually do, could you help me have a workflow to avoid any problems like this? I would like to open a file, make changes to it until I am happy (locally) then when I think it's all working I would like to push all changes... I mean in what order would I have to put, push, pull, commit, add etc... as I don't fully understand the commands either new to them but very exited and interested to learn (the GUI syndrome [joke])
  • John Szakmeister
    John Szakmeister about 11 years
    I think most people use git pull, though I don't personally like that solution. I tend to use the rebase workflow. So I'd do a git fetch --all, git rebase @{u}, test, and git push. The first command fetches the latest data from the remote, the second rebases my changes on top of the most recent commits upstream, then I test, and finally push my changes. If new stuff showed up, I start the process over again. I also often do work in separate branches, then on master do git fetch --all, git merge --ff-only @{u}, then merge the branch, test, and push. This is what I use most.