DEV Community

AJ Kerrigan
AJ Kerrigan

Posted on

Git: Pull and Fetch, When and Why?

The Question

I saw a poll pop up in my Mastodon feed:

Mastodon poll about git pull vs. git fetch

And my brain snagged on it. Because it reminded me that I developed some preferences, built them into aliases, and then shoved them comfortably below the level of conscious thought. And hey, that hasn't caused a problem for me so far! It's still good to re-evaluate these things from time to time though. So when I need to grab some upstream changes with git, what do I do?

Note: I don't intend this as expert guidance - I am neither expert nor guide.

Simple Case

Situation: My active local branch is behind its upstream counterpart.

I...

  • Run git f (an alias which in my head means "freshen up").
  • Under the covers, this runs a git pull and I'm up to date. Yay!

More Complex Case

Situation: I'm working on a branch and want to pull updates in from another branch (typically main).

I...

  • Run git f main.
  • Under the covers, this runs a git fetch command that updates my local main branch from its upstream remote, but leaves my current branch alone.
  • Then depending on the situation, I might:
    • git merge main (perhaps I'm making minor maintainer edits to a community pull request)
    • git rebase main (it's my own junk and I just want to be updated)
    • git rebase -i main (I've got some fine-tuning to do)

Is This Working?

I haven't really interrogated my instincts in a while, so does this flow still work for me?

Yeah, I think so. It tucks most of my "get me up to date" behavior behind a single alias, and deliberately leaves me to make a judgement call in cases where the next step is less certain.

For the record, here's the full picture of what git f does:

#!/usr/bin/env bash
set -euxo pipefail

if [[ -z "${1:-}" ]]; then
    git pull -v
else
    git rev-parse --abbrev-ref "${1}"@{upstream} | \
        awk '{split ($0,ref,"/"); system("git fetch -v --prune " ref[1] " " ref[2] ":" ref[2]); }'
fi
Enter fullscreen mode Exit fullscreen mode

That else clause feels a bit weird. But it means when I run git f main:

  • That git rev-parse bit finds whichever remote is upstream of main. Let's say that's called origin.
  • Something like git fetch origin main:main updates my local main branch, but leaves my active branch alone.
    • --prune does a bit of tidying while we're at it, removing local branches that were tracking remote branches that no longer exist

There's undoubtedly a better/smarter way to handle this workflow, express it in bash, or both. Suggestions welcome in the comments!

Top comments (0)