Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

After git fetch, how to fast forward my branch?

+6
−0

I did git fetch to quickly get latest commits. I did this instead of git pull so I could deal with merge conflicts offline. But my repository is still stuck on the old commit, and now git pull fails because I can no longer connect to the internet. How do I "activate" the changes that I fetched?

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

2 answers

+5
−0

tl;dr

git merge origin/branch_name

Or rebase instead of merge

Long answer

When your local repository has one or more remotes configured, there are special branches that the documentation calls "remote-tracking branches".

Basically, those branches serve "as bookmarks, to remind you where the branches in your remote repositories were the last time you connected to them". Their names follow the format "remote_name/branch_name".

Example: let's say there is some remote repository, which has just the branch main. After cloning it (git clone remote-url), the situation will be like this:

Remote
All previous commits... <- commit A (main)

Local (after git clone)
All previous commits... <- commit A (main, origin/main)

Your local repository has the local branch main, and the remote-tracking branch origin/main (both pointing to the same commit A). The latter indicates the state of the branch main in the remote repository when you cloned it.

Now let's say someone else pushed to the remote repository, while you also changed your local one:

Remote (someone else pushed commit B)
All previous commits... <- commit A <- commit B (main)

Local (you added commit C)
All previous commits... <- commit A (origin/main) <- commit C (main)

Note that the changes you made locally affected only your local branch main. The remote-tracking branch origin/main still points to commit A, because that's the status it got the last time you synchronized with the remote (in this case, when you cloned it). Your local repository is still unaware of commit B.

You can't move remote-tracking branches. They are moved by Git when you synchronize with the remote repository (when you clone, fetch, pull or push).

So let's get the new commits from the remote, by running git fetch. The result will be:

Remote
All previous commits... <- commit A <- commit B (main)

Local (after git fetch)
All previous commits... <- commit A <- commit C (main)
                              ↑
                           commit B (origin/main)

After fetching, your local repository is updated with the current status of the remote repository. In this case, the only change is: "branch main in the remote repository is pointing to commit B, whose parent is commit A". That's why origin/main in the local repository now points to commit B.

Therefore, in order to update your local branch main, you just need to merge it with origin/main (either by using git merge or git rebase, it depends on your preferences or specific project workflow, etc).


By the way, the documentation says:

"git pull runs git fetch with the given parameters and then depending on configuration options or command line flags, will call either git rebase or git merge to reconcile diverging branches".

Which means that, when you fetched, you already did the first part of git pull, and a simple merge or rebase is enough to complete it.

But there's a corner case. Let's say you fetch, review and merge, but while you were reviewing, someone else pushed new commits. If you just merge instead of pulling, you won't get those new commits, as you're merging only the ones you've got when you fetched. But of course you could pull (or fetch+merge) again to get the remaining commits when your network is back.


PS: I'm assuming your remote's name is "origin" (which usually is, for most cases). But of course this explanation is valid for any remotes you might have configured, and you just need to change its name in the command line.

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

0 comment threads

+3
−0

The answer by hkotsubo is correct. But just in case you're being very specific about fast-forwarding, it's worth stressing that you can use --ff-only as an option on the merge to abort if it requires a merge commit.

git merge --ff-only origin/branch_name

Where is this useful? I have my git pull set to fail if the merge would create a merge commit. Typically, I'd rather rebase my new commits than make a merge commit unnecessarily.

[pull]
    ff = only

But that only happens for pulls.[1] If I explicitly ask for a merge after fetching, Git's going to give me a merge, even if it makes a merge commit… unless I --ff-only it not to.


  1. This configuration can be added for merges as well as for pulls, but I find that the pull.ff config set to only gives me the confidence to pull whenever I want. If a fast forward is unavailable, Git just does a fetch without merging. I don't bother setting merge.ff to only, since I only ever git merge commits I already have locally and I'm pretty cognizant of when it'll merge or fast forward. ↩︎

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

1 comment thread

Prettyprint (1 comment)

Sign up to answer this question »