7
2
I'm failing to understand how to use git-rebase
, and I consider the following example.
Let's start a repository in ~/tmp/repo
:
$ git init
Then add a file foo
$ echo "hello world" > foo
which is then added and committed:
$ git add foo
$ git commit -m "Added foo"
Next, I started a remote repository. In ~/tmp/bare.git
I ran
$ git init --bare
In order to link repo
to bare.git
I ran
$ git remote add origin ../bare.git/
$ git push --set-upstream origin master
Next, lets branch, add a file and set an upstream for the new branch b1
:
$ git checkout -b b1
$ echo "bar" > foo2
$ git add foo2
$ git commit -m "add foo2 in b1"
$ git push --set-upstream origin b1
Now it is time to switch back to master
and change something there:
$ echo "change foo" > foo
$ git commit -a -m "changed foo in master"
$ git push
At this point in master
the file foo
contain changed foo, while in b1
it is still hello world. Finally, I want to sync b1
with the progress made in master
.
$ git checkout b1
$ git fetch origin
$ git rebase origin/master
At this point git st
returns:
# On branch b1
# Your branch and 'origin/b1' have diverged,
# and have 2 and 1 different commit each, respectively.
# (use "git pull" to merge the remote branch into yours)
#
nothing to commit, working directory clean
At this point the content of foo
in the branch b1
is change foo as well. So what does this warning mean? I expected I should do a git push
, git suggests to do git pull
... According to this answer, this is more or less it, and in his comment @FrerichRaabe explicitly say that I don't need to do a pull. What's going on here? What is the danger, how should one proceed? How should the history be kept consistent? What is the interplay between the case described above and the following citation:
Do not rebase commits that you have pushed to a public repository.
taken from pro git book.
I guess it is somehow related, and if not I would love to know why. What's the relation between the above scenario and the procedure I described in this post.
The reason
git st
gives that output is because git knows that your localb1
branch is trackingorigin/b1
, so that's what you want to rebase onto. You rangit rebase origin/master
though, so you rebased ("replayed") yourb1
commits on top oforigin/master
. – Frerich Raabe – 2013-10-30T08:18:06.603@FrerichRaabe: Let me try and rephrase. You say that assuming
origin/master
andmaster
are updated, I should rebaseorigin/b1
onorigin/master
, and then dogit pull
whenb1
is checked out to pull the rebase to the local repository? – Dror – 2013-10-30T09:07:13.837No, you don't need a
git pull
and you never rebase a remote branch (e.g.origin/master
) on anything else. – Frerich Raabe – 2013-10-30T10:17:20.757@FrerichRaabe So what is the right way here? The warnings one gets mean that after the rebase
origin/b1
andb1
are not the same. This is rather obvious, but what's the right way to fix it? Or does fixing it means messing the history as @heavyd explained? – Dror – 2013-10-30T11:20:33.763I don't know what the "right way" is because I don't know what you're trying to do. You clearly rebased
b1
ontomaster
and that means thatb1
andorigin/b1
diverged. I suggest that you rungitk --all
in your repository to see a visualization of what happened. Note thatb1
is repased ontomaster
, i.e. anything inmaster
is also contained inb1
. Butorigin/b1
is still the same as before. To change this, you could do agit push --force
... – Frerich Raabe – 2013-10-30T12:59:16.590...which means that
origin/b1
will be made to point to the same thing yourb1
points to. But this means that you rebased a branch in a repository which others might have pulled from, which should be done only very carefully as the pro git book correctly notes. – Frerich Raabe – 2013-10-30T13:00:38.393@FrerichRaabe but if I'm the only one (by decision) who pull/pushes to/from
origin/b1
thengit push --force
should be safe, right? I want to haveb1
andorigin/b1
to be in sync. – Dror – 2013-10-30T13:13:55.863You're safe in that case, right. – Frerich Raabe – 2013-10-30T13:24:56.417
1I would add as long as that one repo is the only repo pushing/pulling from the public remote repo you're safe. I've run into problems where I was the only one working on a project, but I'm working from two different machines. If branches ever diverge in that situation you can still have a mess. – heavyd – 2013-10-30T13:28:59.403