22

Let's assume the current branch is MyFeatureX. And the local develop branch is up-to-date with origin. Would the two statements below be equivalent? What is the recommended syntax?

git rebase origin/develop 
git rebase develop 

Please note: This is not the same question as git rebase origin vs.git rebase origin/master

Community
  • 1
  • 1
Polymerase
  • 6,311
  • 11
  • 47
  • 65
  • This appears to be an identical question to the one you linked. The second answer down is probably the most helpful for your case. – Andy Ray Mar 06 '17 at 04:46
  • 1
    How come they are similar? I have no branch named `origin`. In my setting, `origin` is an alias to mean a remote repository (seen by `git remote -v`). I my question here `develop` is a local branch which is tracking the `origin/develop` branch on remote. – Polymerase Mar 06 '17 at 04:54
  • oh, you're right, that question is an unusual use case and I misread it as this case. although it's basically the same under the hood – Andy Ray Mar 06 '17 at 04:56
  • I just commented on that other question, but this is yet another place Git is overly tricky / sneaky. Typically `origin` is the *name of a remote* (hence short for a URL), but in [gitrevisions](https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html) notation, `origin` is short for `origin/HEAD`, which is what Git calls a *symbolic reference*, i.e., a name for yet another name (!). – torek Mar 06 '17 at 04:58

3 Answers3

30

Your local branch develop tracks origin/develop and they might not always have the same commits in them.

$ cat ~/.git/config

[remote "origin"]
    url = git@something.com/repo.git
    fetch = +refs/heads/*:refs/remotes/origin/*

This means we have a "remote" (a repository living somewhere else) arbitrarily named "origin".

Your local develop branch is tracking the branch from that remote repository, and there's a local reference to that data called origin/develop. For the most part, we consider these two things to always contain the same commits. However, you need to explicitly update your local develop branch to get the latest data from origin. This is mostly commonly done with a pull:

$ git status
    on branch develop
$ git pull
    ...pulls latest changes from origin

However, a git pull actually does two steps, a fetch and a merge. The first step it does under the hood is fetch all the latest commits from origin, which you can do with

git fetch origin

This will update the branch origin/develop, but not your local branch develop.

The newest commits are hidden "behind the scenes" in your local .git directory, which you can reference from the branch named "origin/develop".

After a fetch, to actually make your local branch origin, you would have to do git merge origin/develop. This technically isn't a merge, it will be a "fast forward," meaning git is smart enough to make your local origin branch match origin/develop without actually merging anything. For this reason and others, merges freak me out in git.

So if you rebase off of develop, there's a chance it will be out of date (older) than origin/develop.

I personally do this workflow before rebasing:

git fetch --all
git rebase origin/branchname

This means that I can pull all data down without having to think too much about what branch I'm on, and rebase off the latest code from the remote repository. Later, on the develop branch, a simple git pull will make sure you're up to date.

Andy Ray
  • 30,372
  • 14
  • 101
  • 138
  • Nice academic explanation about the synchronization mechanism between local and remote branches. I am relieved to have you guys confirm that `git rebase origin/develop` is equivalent to `git rebase develop`. Providing I must have taken care to keep them in sync. I'll follow your advice, using the `origin/develop` reference. May be this is obvious so that the [git rebase](https://git-scm.com/docs/git-rebase) doesn't mention the details about how to address a "baseBranch". But for a rebase novice, this was quite confusing. – Polymerase Mar 06 '17 at 05:34
4

If develop points to the same commit as origin/develop then the two commands are exactly the same. I would tend to use origin/develop in case I had forgotten to update my local develop (assuming this branch is eventually going to be pushed to origin/develop).

Penguin Brian
  • 1,991
  • 14
  • 25
1

As I wrote in my other (long) answer to your previous question Why is "rebase --onto ABC" different than "rebase ABC"?, both of these commands turn off --fork-point mode, so—provided that both develop and origin/develop resolve to the same commit hash, as they do in your question premise—the two commands will do the same thing.

Omitting the <upstream> argument turns --fork-point on by default, and the reflog for the branch's configured upstream may have a lot of data in it. In this case, they may act quite differently. By adding an explicit --no-fork-point, you can prevent git merge-base --fork-point from dropping upstream-removed commits.

Community
  • 1
  • 1
torek
  • 448,244
  • 59
  • 642
  • 775
  • super cool, especially for your answer to my other `rebase --onto` question. Please give me sometime to absorb that `--fork-point` business. – Polymerase Mar 06 '17 at 05:26