Skip to content

That one little confusing thing about the Git version control system

by Robb on February 2nd, 2011

Git and github are awesome pieces of software. Last year, I happily switched from subversion to git just like, years ago, I switched from CVS to subversion. Another evolutionary step. I use github for lots of reasons. The biggest is that it’s the best front-end to git that I’ve found. And so now I use git+github for 15 or so projects; some open source like HTTP Assertions, and some private code, like the OregonLaws.org web app.

The one little problem

Everything goes along happily until git decides you need some help. And so, in a fit of well intentioned verbosity, git coughs up three terminology-packed paragraphs of text that we’ve all seen:

You asked me to pull without telling me which branch you want to merge with, and 'branch.newlayout.merge' in your configuration file does not tell me either. Please specify which branch you want to merge on the command line and try again (e.g. 'git pull <repository> <refspec>'). See git-pull(1) for details.

If you often merge with the same branch, you may want to configure the following variables in your configuration file:

branch.newlayout.remote = <nickname>
branch.newlayout.merge = <remote-ref>
remote.<nickname>.url = <url>
remote.<nickname>.fetch = <refspec>

I collected the following git-specific terms from this one message:

branch, fetch, git-pull, merge, newlayout, nickname, pull, refspec, repository, remote, remote-ref, url

What’s the difference between a <refspec> and a <remote-ref>? Between a <repository> and a <nickname>? Between a pull and a merge? (I asked for a pull, but git’s giving me merge info.)

My guess: several of these terms are used interchangeably, and git’s docs should be made more consistent. Note how the terms in the text paragraphs do not match the terms in the config file template.

Problem #2: The second paragraph says to add the info to the config file. But the info isn’t in config file format; it’s closer to command line git config format.

From → Just a Thought

14 Comments
  1. Ben permalink

    ‘pull’ is basically a ‘fetch’ plus a ‘merge’, which is why it’s giving you merge information – your fetch probably ran fine, but it can’t make it past the merge step, because you haven’t given it enough information.

    There’s actually a really good dictionary of terms (including refspec, which seems like the main thing you’re hung up on) in the git user’s manual:
    http://www.kernel.org/pub/software/scm/git/docs/user-manual.html

    In your case, if your local branch is named foo, and you want to merge with the remote branch bar on the remote named baz:

    git checkout foo
    git pull baz bar

    most likely foo and bar are the same, though. and your remote is probably named origin, if you’re using github. and in your example, it looks like your branch is named ‘newlayout’. So you’ll want to do:

    git checkout newlayout
    git pull origin newlayout

  2. `man gitglossary` should give you the information you’re looking for. I found that man page from inside the git manpage.

  3. In actual fact, it IS in config file format. Just try it…

    - ferdy

  4. Yeah, those git messages aren’t great.

    I find, once you set up your “origin”(i.e. Github) ‘remote’ in .git/config, you’re good to go.

    [remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = git@github.com:my_git_user/rad_as_hell_repo.git
    push = +refs/tags/*:refs/tags/*

    GitHub help gives you the command for doing this in one go. Its worth getting familiar with .git/config anyway.

    Re: fetch vs pull: my advice is to get in the habit of using git fetch(+ git rebase), not git pull.

    Sure it might save a keystroke or two, but ‘git pull’ does a fetch *and* a (‘fast-forward’) merge – a strange, and often misunderstood default.

    But when you’re usually just updating your local copy of the branch, a fast forward merge is a nasty way to do that. Git fetch & git rebase is a way better habit to get into.

    This is essential git reading: http://nvie.com/posts/a-successful-git-branching-model/

    Git flow seems popular too – it abstracts a lot of this detail away: http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/

  5. You’ll notice “newlayout” isn’t a git-specific term—it’s your branch’s name.

  6. Robb permalink

    Thanks for the help, everyone.

    @Arlen Doh! You’re right.

  7. Robb permalink

    I’m finding the “Git Reference” to be a big help. http://gitref.org/

    And attempting to parse the man pages…

  8. Andrew permalink

    I typically get this error when I have created a local branch from a remote branch, but forget to create that branch remotely as well. For example, I create branch my_branch locally from origin/master, but I don’t create origin/my_branch. As I haven’t told git what my_branch links to (and there is no origin/my_branch for git to assume is the correct destination), it needs you to configure it.

    So if I see your issue correctly, you need to either tell your config what branch your local my_branch links to or define a branch on origin with the same name and check THAT out locally.

    Feel free to email me if you want to discuss it further.

  9. shadowhand permalink

    A couple solutions to this problem:

    1. Do the obvious thing and change your config:

    # mybranch is your branch name!
    git config branch.mybranch.remote origin
    git config branch.mybranch.merge refs/heads/mybranch

    2. When checking out a remote branch, either use the very verbose tracking method:

    # newbranch is the name of your local branch!
    git branch –track newbranch origin/newbranch
    git checkout newbranch

    Or tell git to automatically configure this stuff:

    git config –global branch.autosetupmerge true

    The branch.autosetupmerge will allow you to do this:

    # newbranch is origin/newbranch and does not exist locally… yet!
    git checkout newbranch

    Personally I use a combination of these two latter methods depending on what I want to do.

  10. 1) The refspec is the path that you’ve given git (explicitly or, more likely, implicitly via another command) for this repo. It tells git what branches you want to pull.
    2) the nickname is the alias for the repository. You’ve probably set up “origin” to be the nickname for your remote repository.
    3) in Git, a pull is effectively an alias for fetch and merge. That’s why you’re getting merge-speak.

    Adding all of this up, Git is complaining because you’re not telling it what branch you want to pull (fetch and merge). Imagine you’re on branch feature1, and you say git pull. Git pull what? git pull origin master? git pull other-remote other-branch?
    So you need to tell git: git pull origin feature1

    Now, back to your refspec. The reason git was blathering about that is because you can set up your refspec to tell git what git pull means by default. It could be handy to do this for branches you’re pulling a lot- like the master branch of the origin repository.

    Unfortunately, I think you’re dead on with your criticism of the docs. More specifically, I think the docs are wonderful, but the terminology is confusing.

    Stick with it, it’s worth your time :)

  11. pull can easily be over ridden to do rebasing instead of merging

    [branch]
    autosetuprebase = always

  12. Josh permalink

    git branch –set-upstream newlayout origin/newlayout

    is what you want to make git pull work properly. See http://stackoverflow.com/questions/520650/how-do-you-make-an-existing-git-branch-track-a-remote-branch.

  13. Eric permalink

    When you perform a “git pull” behind the scenes it is doing a fetch + a merge to complete the action, this is why you see errors regarding merges sometimes when performing a pull.

Trackbacks & Pingbacks

  1. Tweets that mention That one little confusing thing about the Git version control system | The Robb Report -- Topsy.com

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS