Skip to content

Instantly share code, notes, and snippets.

@induratized
Last active May 23, 2025 14:53
Show Gist options
  • Save induratized/4c6da6eba5dd97ba795cf6e740c1a3fb to your computer and use it in GitHub Desktop.
Save induratized/4c6da6eba5dd97ba795cf6e740c1a3fb to your computer and use it in GitHub Desktop.

Question

I have a shallow cloned single branch limited history repo in my local, now i want to checkout another branch from remote , >How do i do that



Got it! You have a shallow clone of a single branch, and now you want to check out another branch from the remote repository.

By default, a shallow clone with --depth and --single-branch only fetches history for that one branch. To switch to another branch, you need to fetch that branch’s data first.

Here’s how to do it:

Step 1: Fetch the new branch from remote

git fetch --depth=1 origin <branch-name>
  • --depth=1 keeps the shallow clone shallow.
  • <branch-name> is the branch you want to check out.

Step 2: Check out the new branch locally

git checkout -b <branch-name> origin/<branch-name>

This creates a new local branch tracking the remote branch.


Example

If you originally cloned main with:

git clone --depth=1 --single-branch --branch main <repo-url>

And now want to check out feature-branch, do:

git fetch --depth=1 origin feature-branch
git checkout -b feature-branch origin/feature-branch

If you want to deepen your shallow clone to include more history or multiple branches later, you can run:

git fetch --deepen=<number>

or

git fetch --unshallow

If you want, I can guide you through commands specific to your situation — just share your current Git commands or error messages!



Question

i tried to run git checkout -b another origin/another but I got error fatal: 'origin/another' is not a commit and a branch 'another' cannot be created from it


Thanks for the context—this error confirms that your shallow clone doesn't have the commit data for origin/another yet. Git can't create a new branch from a reference it hasn't fetched.

To fix this:

✅ Solution: Fetch the specific branch first

Run this:

git fetch origin another --depth=1

Then:

git checkout -b another origin/another

🧠 Why This Happens

When you do a shallow, single-branch clone:

git clone --depth=1 --branch main --single-branch <repo-url>

Git does not fetch refs for other branches—just the one branch you specified.

So, when you later try:

git checkout -b another origin/another

Git can’t find origin/another locally, because it doesn't exist in your shallow clone’s refs or objects.


Let me know if you get a different error after trying the git fetch origin another --depth=1 command.



Question

but as you mentioned earlier I already fetched via

$ git fetch --depth=1 origin



Got it! You ran:

git fetch --depth=1 origin <branch-name>

but still got:

fatal: 'origin/<branch-name>' is not a commit and a branch '<branch-name>' cannot be created from it

That means even after the fetch, Git isn’t seeing origin/<branch-name> locally. This usually happens if:

  • The branch name is wrong or doesn’t exist on the remote.
  • Or your shallow clone setup restricts fetching refs properly.

Quick checks and fixes:

  1. Verify the branch exists on remote

Run:

git ls-remote origin

Look for the exact branch name you want (e.g., refs/heads/another).

If you don’t see the branch, that’s the issue — it doesn’t exist or you misspelled it.


  1. Fetch the branch explicitly

Try:

git fetch origin refs/heads/<branch-name>:refs/remotes/origin/<branch-name> --depth=1

This forces fetching the remote branch ref explicitly.

Then:

git checkout -b <branch-name> origin/<branch-name>

  1. Fetch all remote branches shallowly

If you want to fetch all branches shallowly (not just one), try:

git fetch --depth=1 origin

Then you can list remote branches with:

git branch -r

  1. Alternative: Create a local branch directly

If you want to create a local branch without tracking remote, you can try:

git checkout -b <branch-name>

But this will be an empty branch if you don’t have commits for it yet.


Summary

The error means the remote ref origin/<branch-name> does not exist locally. The main reasons are:

  • The branch doesn’t exist remotely or name is wrong
  • The fetch didn’t bring the ref locally (shallow clone restriction)

Start with checking the branch exists remotely (git ls-remote), then fetch the ref explicitly.


If you want, share:

  • Your exact clone command
  • The branch name you want to check out
  • Output of git ls-remote origin

I can help pinpoint exactly what’s going on.

Question:

I ran command git ls-remote | grep another

and the output was something like 3ffabcb63adde refs/heads/another

I than also ran git branch -r and the output was something like origin/branch_A origin/branch_B

But i could not find in the output below entry origin/another



Perfect — thanks for providing those details. Based on that:

✅ Diagnosis

  • git ls-remote confirms that another does exist on the remote: ✅
  • git branch -r doesn't list origin/another: ❌ This means your local repo has not fetched that branch yet, even though it exists remotely.

That explains the error: origin/another isn’t present locally, so git checkout can’t create a branch from it.


✅ Correct Fix: Fetch the branch explicitly into local refs

Run this command:

git fetch origin refs/heads/another:refs/remotes/origin/another --depth=1

Then:

git checkout -b another origin/another

🔍 Why this works

That fetch command explicitly maps the remote ref refs/heads/another to your local refs/remotes/origin/another, bypassing shallow clone limitations that sometimes omit branch references in standard fetches.

Now that origin/another exists locally, you can safely check it out.


Let me know if you'd like to make this branch track upstream automatically or convert your repo to a full clone later.

Question:

I will do this but first answer my query, when i first did 'git fetch --depth=1 origin another' where did it put the another branch in my local ? in 'refs/heads' or in 'refs/remotes/origin/' ? also after observation I see that 'another' branch only exists in 'refs/heads/' and not in 'refs/remotes/origin/' , is that possible ? ideally by logic a remote branch once fetched should first land in 'refs/remotes/' and when a local branch is checked out from it then its tracking is made in 'refs/heads, right ?



Great question! You’re digging into how Git manages refs under the hood, which is super useful.


When you run:

git fetch --depth=1 origin another

Where does Git put that fetched branch?

  • Normally, when you fetch a remote branch (like another from origin), Git stores it as a remote-tracking branch under:
refs/remotes/origin/another
  • This means the branch lives as a remote ref first, not as a local branch.

  • You don’t get a new branch under refs/heads/ automatically unless you explicitly create it by checking out or creating a branch:

git checkout -b another origin/another

or

git switch -c another origin/another

Why do you see another only under refs/heads/ and not under refs/remotes/origin/?

This is unusual and typically happens if:

  1. You or some command created a local branch another manually without setting it to track the remote branch properly.

  2. Or the shallow fetch you did fetched the commits and updated a local branch directly, which can happen if you did:

git fetch origin another:another --depth=1

(note the colon syntax: <src>:<dst>), which means fetch remote branch another into local branch another.


Summary of usual behavior:

Action Result
git fetch origin another Updates refs/remotes/origin/another
git checkout -b another origin/another Creates refs/heads/another tracking origin/another
git fetch origin another:another Updates refs/heads/another directly

What you want for standard workflow

  • Fetch remote branch into remote tracking:
git fetch origin another
  • Then create a local branch that tracks it:
git checkout -b another origin/another

This will:

  • Create refs/remotes/origin/another on fetch
  • Create refs/heads/another on checkout (local branch)
  • Set up tracking info linking local branch to remote

To inspect the refs directly, you can look in .git/refs/:

  • refs/heads/ — local branches
  • refs/remotes/origin/ — remote tracking branches

Or list refs via:

git show-ref

If you want, I can explain how shallow clones and fetch behave differently and how that can affect ref updates. Want me to?

Question:

thanks, now going back the previous question, what does this command do? git fetch origin refs/heads/another:refs/remotes/origin/another --depth=1



Great follow-up! Let’s break down exactly what this command does:


Command:

git fetch origin refs/heads/another:refs/remotes/origin/another --depth=1

What happens here step-by-step:

  1. git fetch origin
    This tells Git to fetch from the remote named origin.

  2. refs/heads/another:refs/remotes/origin/another
    This is a refspec telling Git exactly which references to fetch and where to put them locally. The general form is:

    <src>:<dst>
    
    • <src> is the remote ref on origin (in this case, the branch another under refs/heads/)
    • <dst> is the local ref to update (in this case, the remote-tracking branch refs/remotes/origin/another)

    So this tells Git:

    "Fetch the remote branch another and store it locally as refs/remotes/origin/another"

  3. --depth=1
    This limits the fetch to just the latest commit (shallow fetch) for efficiency — you only get the latest snapshot and not the full history.


Why is this useful?

  • Normally, git fetch origin another would fetch the remote branch and place it under refs/remotes/origin/another by default — this is standard.

  • But sometimes, especially with shallow clones or if refs weren’t fetched properly before, Git might not update your remote-tracking refs.

  • This explicit refspec ensures the remote branch another is created or updated in your local refs/remotes/origin/another, even if it was missing before.


Summary:

Part Meaning
refs/heads/another The remote branch another on origin
refs/remotes/origin/another Your local remote-tracking branch for another

This command explicitly syncs that remote branch into your local remote-tracking refs.


After running this, you can:

git checkout -b another origin/another

to create and switch to a local branch tracking that remote branch.


If you want, I can also explain why shallow clones sometimes mess with fetching refs and how this refspec command helps fix that. Would you like?

Question:

after running 'git fetch origin refs/heads/another:refs/remotes/origin/another --depth=1' i can now checkout the another branch,


 ---

Awesome! That means the explicit fetch with the refspec worked perfectly — you now have the remote-tracking ref for another locally, so Git can create the local branch from it.

If you want, here’s a quick checklist to keep things smooth going forward:

  • To switch and track remote branches cleanly:

    git checkout -b another origin/another
  • To fetch other branches similarly, just replace another with the branch name.

  • If you want your shallow clone to gradually deepen (get more history), you can do:

    git fetch --deepen=10
  • And if you ever want the full history and all branches:

    git fetch --unshallow

If you want help setting up tracking or cleaning up branches or anything else Git-related, just ask! Congrats on getting that branch checked out! 🎉

Question

cool, thanks

but now when I try to $ git pull OR $ git pull origin another then I get 'fatal: unable to access : Recv failure: Connection reset by peer' error

similarly when 'git push" i get error

fatal: The current branch another has no upstream branch. To push the current branch and set the remote as upstream, use

git push --set-upstream origin another

Cool, let's tackle these one by one.


1. git pull failing with:

fatal: unable to access : Recv failure: Connection reset by peer

This error usually means a network problem or that the remote server closed the connection unexpectedly. Some common causes and fixes:

  • Network issues: Check your internet connection or VPN/proxy if you're using one.
  • Firewall or Antivirus: Sometimes these block Git traffic—try disabling them temporarily.
  • Remote server problems: The remote server might be overloaded or rejecting connections. Try again later.
  • SSL or TLS issues: Your Git or curl client might have issues with SSL certificates.

Try this:

git fetch origin another

Does it fail the same way? If yes, try running with verbose/debug to get more info:

GIT_CURL_VERBOSE=1 git fetch origin another

2. git push error:

fatal: The current branch another has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin another

This is normal if you created the branch locally and haven't told Git which remote branch it should track.

Fix:

Run exactly:

git push --set-upstream origin another

This:

  • Pushes your local another branch to remote origin
  • Sets up tracking so future git pull and git push commands work without extra options

TL;DR:

  • Fix the push by running:

    git push --set-upstream origin another
  • For the network error on pull/fetch, check network, VPN, firewall, or run with verbose flags to get more debug info.


If you want, share the output of:

GIT_CURL_VERBOSE=1 git fetch origin another

and I can help debug the connection reset issue in detail!

Question

does 'git push --set-upstream origin another' exactly do ?


 ---

Great question! Here’s exactly what this command does:


git push --set-upstream origin another

Breakdown:

  • git push: Pushes commits from your local branch to the remote repository.

  • origin: The name of the remote you’re pushing to (usually the default remote).

  • another: The branch name you’re pushing to on the remote (and also your local branch name here).

  • --set-upstream (or -u): This tells Git to:

    1. Push your local branch another to the remote branch origin/another (creating it if it doesn’t exist).

    2. Set the local branch another to track the remote branch origin/another.


What does "tracking" mean?

Tracking means your local branch is linked to a remote branch, so you can do simple commands like:

  • git pull (which fetches and merges changes from the tracked remote branch)
  • git push (which pushes changes to the tracked remote branch)

without needing to specify the remote or branch explicitly every time.


Without --set-upstream:

If your branch has no upstream configured, Git will complain when you try to push or pull, because it doesn’t know which remote branch to sync with.


So running

git push --set-upstream origin another

does two things at once:

  • Push your current local branch commits to origin/another.
  • Set your local branch another to track origin/another for easy future pulls/pushes.

Tip: You can also use shorthand:

git push -u origin another

It’s exactly the same.


If you want, I can explain how to check what your current branches are tracking or how to change upstream branches later!

Question:

what is the diff between refs/heads and refs/remotes


 ---

Great question — this is key to understanding how Git handles local vs. remote branches.

refs/heads/

  • This is where Git stores local branch references.
  • Each branch in your local repository (e.g., main, feature/login) is a file under .git/refs/heads/.
  • Example:
    If you have a local branch called main, you'll see:
    .git/refs/heads/main
    

refs/remotes/

  • This is where Git stores remote-tracking branches.
  • These reflect the state of branches on a remote (like origin), the last time you fetched from it.
  • Example:
    If you fetched from origin, and it has a main branch, you'll see:
    .git/refs/remotes/origin/main
    

🔄 How They Relate

  • refs/heads/main is your local branch.
  • refs/remotes/origin/main is your view of the main branch on the remote, updated by git fetch.

When you do:

git fetch origin

→ It updates refs/remotes/origin/*
But when you do:

git merge origin/main

→ It brings changes from the remote-tracking branch into your local branch.


Summary

Ref Type Purpose Example Path
refs/heads/ Local branches .git/refs/heads/feature-x
refs/remotes/ Remote-tracking branches .git/refs/remotes/origin/main

Let me know if you want a visual explanation or a demo repo setup.

Question:

how are these two linked?


 ---

Great follow-up! The link between refs/heads/ (local branches) and refs/remotes/ (remote-tracking branches) is what lets Git keep your local work in sync with the remote repository.

How are refs/heads/ and refs/remotes/ linked?

  1. Remote-tracking branches reflect the last known state of branches on the remote.

    • When you run git fetch origin, Git updates refs/remotes/origin/* to match what’s on the remote server.
    • These are read-only snapshots; you don’t work on these directly.
  2. Local branches track remote-tracking branches.

    • Your local branch (e.g., main) can be configured to track a remote-tracking branch (e.g., origin/main).
    • This tracking setup lets Git know which remote branch your local branch is related to — useful for git pull, git push, and status commands.
  3. Tracking allows automatic synchronization commands

    • For example, when you run git pull on a branch set to track origin/main, Git will:

      • Fetch the remote changes into refs/remotes/origin/main
      • Merge those changes into your local refs/heads/main
  4. You can see the tracking information

    • Use:

      git branch -vv

      It shows local branches with their upstream remote-tracking branch and if they are ahead/behind.


Example:

  • You have a local branch main:

    refs/heads/main
    
  • Your remote is origin, and the remote branch is main:

    refs/remotes/origin/main
    

When you create your local branch with tracking:

git checkout -b main origin/main
# or
git branch --set-upstream-to=origin/main main

Now main is linked to origin/main.


Summary in plain terms:

  • Remote-tracking branches (refs/remotes/origin/*) are like snapshots of the remote repo.
  • Local branches (refs/heads/*) are your working branches.
  • Tracking links tell Git which remote branch your local branch is related to, enabling sync commands to know what to compare, fetch, merge, or push.

Want me to show how to check or set this tracking, or what happens under the hood during push/pull?

Question::

my bad , the another branch refs/heads exists in remote origin


Ah, got it! You’re saying that another branch with the same name exists on the remote origin as well as locally, and you want to understand how refs/heads (local) and refs/remotes (remote-tracking) relate in that scenario. Perfect — let me clarify that in context.


When a branch exists both locally and remotely (same branch name)

Suppose:

  • You have a branch called feature-x locally:
    refs/heads/feature-x
  • There is also a branch called feature-x on the remote origin:
    refs/remotes/origin/feature-x

How Git handles this

  1. Local branch feature-x is your working branch.

  2. Remote-tracking branch origin/feature-x is your last fetched snapshot of that remote branch.

  3. The two are connected if your local branch feature-x is set to track origin/feature-x. This means:

    • When you run git fetch origin, Git updates refs/remotes/origin/feature-x to the latest remote commit.
    • When you run git pull on your local feature-x branch, Git merges the changes from origin/feature-x into your local feature-x.
    • When you run git push from your local feature-x, it updates the remote feature-x branch (on origin).

How to check if your local branch tracks the remote one:

git branch -vv

Sample output might look like:

* feature-x  abc1234 [origin/feature-x] Some commit message

The [origin/feature-x] indicates your local branch is tracking the remote origin/feature-x.


How to set up tracking if it’s not set

git branch --set-upstream-to=origin/feature-x feature-x

or if you want to create the local branch tracking remote right away:

git checkout --track origin/feature-x

Why is this useful?

  • It lets you work locally on feature-x, while staying in sync with the remote branch of the same name.
  • Git commands like git status, git pull, git push work automatically with the right remote branch.

Summary

Location Branch Name Purpose
refs/heads/feature-x feature-x (local) Your local working branch
refs/remotes/origin/feature-x feature-x on origin Remote snapshot of branch feature-x

If you want, I can explain how to handle divergence between local and remote branches, or how to resolve conflicts if they differ!

Question::

no not locally


Gotcha — you mean the branch refs/heads/feature-x exists on the remote origin, but you don’t have it locally yet?


What’s going on then?

  • On the remote origin, there is a branch called feature-x (stored as refs/heads/feature-x on the remote repo).

  • On your local repo, this branch does not exist yet in refs/heads/ because you haven’t created or checked it out.

  • However, after you run:

    git fetch origin

    Git will create/update the remote-tracking branch for that remote branch in:

    refs/remotes/origin/feature-x
    
  • This remote-tracking branch represents that remote branch, but locally you still don’t have a refs/heads/feature-x branch unless you explicitly create it.


So basically:

Ref name Location What it means
refs/heads/feature-x Remote repo The branch on the remote repository (origin)
refs/remotes/origin/feature-x Your local repo Your local snapshot of the remote branch after fetching
refs/heads/feature-x Your local repo Your actual local branch (may or may not exist)

How to get that remote branch locally?

You have to create a local branch that tracks it:

git checkout --track origin/feature-x

or (if you want to create without switching)

git branch feature-x origin/feature-x

Recap

  • Branches on remote live in refs/heads/ in the remote repo.
  • Your local repo stores remote branches as refs/remotes/origin/.
  • You only get a local branch under refs/heads/ if you create or check out that branch locally.

If you want, I can guide you step-by-step on how to fetch and track remote branches you don’t have locally yet!

Question::

let me know how to list refs/heads and refs/remotes in my local?


Sure! Here’s how to list the branches under refs/heads (local branches) and refs/remotes (remote-tracking branches) in your local repo:


1. List local branches (refs/heads)

Use:

git branch

or more explicitly to see the actual refs:

git show-ref --heads

This lists all the local branches with their commit hashes, because --heads filters to refs under refs/heads.


2. List remote-tracking branches (refs/remotes)

Use:

git branch -r

or explicitly with show-ref:

git show-ref --remotes

This lists all remote-tracking branches with commit hashes (refs/remotes/*).


3. List both local and remote branches at once:

git branch -a
  • -a means all branches (local + remotes).
  • Output will look like:
  main
  feature-x
  remotes/origin/HEAD -> origin/main
  remotes/origin/main
  remotes/origin/feature-x

Bonus: list refs directly from .git folder (for advanced use)

If you want to see the actual files on disk:

ls .git/refs/heads/
ls .git/refs/remotes/

But these don’t always tell the full story because of packed refs, so using git show-ref is more reliable.


Let me know if you want me to help parse the output or explain any specific branch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment