TL;DR
You don't have both a repository and a branch here. Instead, you have a tree-ish and a pathspec. The tree-ish is a commit specifier, origin
, which is short for origin/HEAD
, which is short for ... well, see below. The pathspec is develop
which just means the file named develop
. If there is no such file, this command will simply fail.
Long: how to read Git documentation
The syntax for git checkout
is:
git checkout [-q] [-f] [-m] [<branch>]
git checkout [-q] [-f] [-m] --detach [<branch>]
git checkout [-q] [-f] [-m] [--detach] <commit>
git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
git checkout [<tree-ish>] [--] <pathspec>...
git checkout (-p|--patch) [<tree-ish>] [--] [<paths>...]
None of these allow you to specify a branch name twice.
Try matching:
git checkout origin develop
to the above seven possible syntax lines. It doesn't match #1, which allows only one <branch>
argument and no additional arguments. It doesn't match #2, which requires a literal --detach
. It doesn't match #3, which allows only one <commit>
argument and no daditional arguments. It doesn't match #4, which allows only one optional <start-point>
argument, and it doesn't match #7, which requires a literal -p
or --patch
.
It does match #5 and #6. These probably shouldn't be two separate syntax lines, and in the subsequent description section, they aren't—it's just one section with:
git checkout [<tree-ish>] -- [<pathspec> ...]
which has the flaw that it fails to mention all the optional flags in the shortened summary, but it then mentions those flags in the body of the text:
Overwrite paths in the working tree by replacing with the contents
in the index or in the <tree-ish> (most often a commit). When a
<tree-ish> is given, the paths that match the <pathspec> are
updated both in the index and in the working tree.
The index may contain unmerged entries because of a previous failed
merge. By default ...
[snip - this is where flags like -f
and --ours
and so on get mentioned]
Now, this text is full of Git jargon, in particular tree-ish and pathspec. (Side note: tree-ish is defined in the Gitglossary, but I'm going to use a more pointed defintion here.)
The term tree-ish means: I, Git, am fine here if you name a specific commit. All I'm going to do with the commit is find its internal tree object, so you can give me that directly, if for some odd reason you really want to. But really, just gimme something I can translate to a commit or tree, and I'll use the tree, or use the commit to find the tree.
You provided origin
here, and now it's time to go look at another piece of Git documentation. (What, another one? Already?) The gitrevisions documentation describes a six-step process for turning a name, like master
or develop
or v2.1
, into a Git object hash ID.
The first step is to check whether there is a file in .git
that has that name, and that step lets you use a name like CHERRY_PICK_HEAD
while you're in the middle of a conflicted git cherry-pick
. In this case, it doesn't apply.
The second step is to try the name as refs/name
. That second step lets you use stash
or stash@{number}
when you are using git stash
. In this case, it doesn't apply either.
The third step is to try the name as refs/tags/name
. That third step lets you use a name like v2.1
to refer to the tag v2.1
. Since origin
probably is not a valid tag name—you didn't tag any of your commits origin
, did you?—this step is going to fail, so Git will move on to step #4.
The fourth step is to try the name as refs/heads/name
. This step allows you to use a branch name to specify a commit. That's what lets you git checkout master -- somefile
, for instance. Since master
is a valid branch name, git checkout
will find the specific commit that master
names—the tip of the master
branch—and use that commit's tree—remember, we're executing the git checkout <tree-ish> [--] <pathspec>...
syntax, and working on the <tree-ish>
part here.
But you don't have a branch named origin
, do you? You might, if you created one! I'd advise against creating one, but if you did, that's where this six-step process will stop. Assuming you don't, though, the process goes on to step five.
Step five tries the name as refs/remotes/name
. You will have a directory named refs/remotes/origin/
but that's not a valid ref so step five will fail, and the process will move to the last step. If the last step fails, the whole thing fails, but...
Step six, the final one, tries the name as refs/remotes/name/HEAD
. Since origin
is a valid remote, this will exist (well, unless you specifically deleted it, or in one other case that's not going to occur), and will be a valid commit specifier. So step six succeeds: it finds that refs/remotes/origin/HEAD
exists and (probably) names refs/remotes/origin/master
, which also exists, and that names a commit.
Thus, at this point the <tree-ish>
part of the whole process is satisified: Git has translated origin
to refs/remotes/origin/HEAD
, or origin/HEAD
for short; that's (probably) the same as refs/remotes/origin/master
, or origin/master
for short; and that's a valid commit, which would serve for either git checkout
syntax rule #3 or for git checkout
syntax rules #5 & #6.
Since we're working on the #5/#6 rules, we can go on and treat the last argument, develop
, as a <pathspec>
. Now we have to look at yet another piece of Git documentation, namely the Gitglossary. We can jump straight to the definition of a pathspec, which is, unfortunately, very long and I'm not going to go through all of it here.
To sum up, though, a pathspec can be, and in this case is, just a file name. So develop
becomes a file name, and we have finished all the requirements for syntax rule(s) #5/#6. Git will execute the action described in the yellow quoted text above, replacing the file develop
in the index and work-tree, or simply erroring-out if the file develop
does not exist by that name in the commit/<tree-ish>
that we chose with the name origin
.