Reputation: 11389
I created a branch to develop a new feature. Since this new feature was develop entirely as a new project, the only possible source of conflict would be in the solution file.
As the feature was developed, the master branch was updated several times. When I completed my development and testing, I did:
git checkout master
git fetch
git pull
git checkout myFeature
git rebase master
The rebase (and all other commands) went fine and no conflicts/errors/problems were reported. My next step was to git status
and the result was:
On branch myFeature
Your branch and 'origin/myFeature' have diverged, and have 7 and 5 different commits each, respectively. (use "git pull" to merge the remote branch into yours)
When I git pull
a merge was open and looking at the history, my commits were duplicated. This duplication, in my point of view was not supposed to happen. I was expecting that my commits were supposed to be re-applied AFTER the last (currently) commit on the master.
Am I doing something wrong or my expectation is wrong?
Upvotes: 5
Views: 3289
Reputation: 1683
This part was enough for rebasing with master
branch.
git checkout master
git fetch
git pull
git checkout myFeature
git rebase master
However, you can just use the following command instead of all the above command to do the same thing.
$ git pull origin master --rebase
After this all the commit hash will be rewritten that's why git status
showed that your branch has diverged.
Ignoring this, you could run the following command to push the rebased code to the remote branch.
$ git push origin HEAD -f
While rebasing if you face conflicts and you are not willing to continue the rebase, you can just run git rebase --abort
to abort the rebasing.
In any case, if you find yourself in the middle of some unwanted commit related hazard, you can follow the following steps.
git reflog
- to find the last perfect commit & note its commit hashgit reset --hard <commit-hash>
- provide the last perfect commit hashIt will take you to the last perfect code of the repo.
Upvotes: 1
Reputation: 1475
The previous answer looks great. Just trying to illustrate visually what's going, in case that's helpful:
Since git rebase
modifies history, you branch after rebasing looks different from the one you have on origin.
origin/master:
A -> B -> C -> D -> E
yourbranch, origin/yourbranch:
A -> B -> F -> G -> H
After rebasing, yourbranch would look like:
A -> B -> C -> D -> E -> F -> G -> H
Then, when you pull origin/yourbranch, you would have:
A -> B -> C -> D -> E -> F -> G -> H - I (merge commit)
\ /
-> F -> G -> H -------------
Since the histories are different, it becomes a normal, non-fast-forward merge. Effectively, your remote and local branches have become different branches.
Upvotes: 3
Reputation: 36710
When you do a rebase, you're changing Git history. When you do a pull again, Git tries to combine both histories again. As by default git pull
is a git fetch
+ git merge
, this will lead to a merge commit.
This isn't what you want after changing history as it will (partly) reverts you history changes. Unfortunately the hint of git status
is a bit misleading...
After changing history (e.g. rebase), you need a force push so you will get that history also on the remote. You're telling git then "the history is different, but trust me, that's intended".
It's recommend to use a "force push with lease": git push --force-with-lease
- see git push --force-with-lease vs. --force.
Luckily you could go back before the git pull
by using the Git reflog!
This will fix the wrong pull and there won't be any conflicts to solve :)
So steps to do:
git reflog
, so before the git pull
(note: you could quit the reflog by typing q) git reset 327fb961e --hard
git push --force-with-lease
. Note: if you are making a mistake with git reset
, you could use the git reflog
again :)
Note 2: the reflog is only on your local machine
Upvotes: 12