Skip to content

Git and GitHub Answers: The Questions People Actually Search

Most of these questions arrive as an error message pasted into a search box. The answer is usually one or two sentences, and then the interesting part is why — which is what the linked lesson is for.

Every answer below states the thing itself first, in sentences that stay true on their own. Under each one is the command from the lesson it came from, the qualification that stops it being misread, and a link to the full explanation.

Install & identity

Git says "Author identity unknown". What do I run?

Searched as git author identity is not configured. run `git config --global user.name "your name"` …

Run the two commands Git prints: git config --global user.email "you@example.com" and git config --global user.name "Your Name". Nothing was committed, so commit again afterwards.

git config --global user.email "you@example.com"
git config --global user.name "Your Name"

Omit --global to set the identity only in the current repository. Editors paraphrase this as "author identity is not configured"; the fix is the same.

Install Git on Ubuntu →

Why does git --version say "(Apple Git-154)"?

Searched as git version 2.39.5 (apple git-154)

Because that is Apple’s build of Git, shipped with the command line developer tools and versioned on Apple’s schedule rather than Git’s. It is a real, working Git.

brew install git
which git   # shows which Git is winning

For a current upstream release, install Git with Homebrew and make sure /opt/homebrew/bin precedes /usr/bin on your PATH.

Install Git on macOS →

"The git command requires the command line developer tools" — is that an error?

Searched as the git command requires the command line developer tools

No. That dialog is macOS offering to install the tools, so it is the installer rather than a failure. Click Install, or run xcode-select --install from the terminal.

xcode-select --install

Either route gives you Apple’s build of Git, not the latest upstream release.

Install Git on macOS →

How do I install Git on Windows with winget?

Searched as winget install git

Run winget install --id Git.Git -e --source winget, then open a new terminal. The installer updates PATH, but a shell reads PATH when it starts, so the window you installed from still cannot find git.

winget install --id Git.Git -e --source winget

Git Bash, PowerShell and Command Prompt all run Git identically. core.autocrlf=true is the right Windows default, and a committed .gitattributes is the better team-wide fix.

Install Git on Windows →

What is the difference between Git and GitHub?

Searched as gh vs git

Git is a command-line program that manages a repository on your own filesystem. GitHub is a hosted service that stores Git repositories on servers, plus everything built around that hosting. Git works completely without it.

git init        # Git: local, no network
gh repo create  # GitHub CLI: talks to the service

Pull requests, Actions, issues and reviews are GitHub features, not Git features.

Git vs GitHub →

HEAD & history

Why does git rev-parse --abbrev-ref HEAD print "HEAD"?

Searched as git rev-parse --abbrev-ref head detached head documentation

Because you are in detached HEAD state: HEAD points straight at a commit instead of a branch, so there is no branch name to print and the literal string HEAD comes back instead.

git rev-parse --abbrev-ref HEAD   # "HEAD" when detached
git switch -c my-branch           # keep the work on a branch

Detached HEAD is not an error. It is the normal state during a checkout of a commit or tag, a bisect, and an interactive rebase. Commits made there belong to no branch until you create one.

HEAD →

How do I undo the last commit?

One question decides it: has the commit been pushed anywhere others have pulled? If not, amend, reset or rebase interactively. If it has, add a new commit that undoes it with git revert instead of rewriting shared history.

git commit --amend        # fix the message or add a forgotten file
git reset --soft HEAD~1   # undo the commit, keep the changes staged
git revert <sha>          # undo a commit that is already shared

amend and reset rewrite history; revert does not. Picking the wrong one on a shared branch is the mistake that costs a team an afternoon.

Editing commit history →

Can I have two branches checked out at the same time?

Yes, with git worktree. It gives one repository several working directories, each on its own branch, sharing a single object store.

git worktree add ../hotfix hotfix/login
git worktree list
git worktree remove ../hotfix

This is the interruption workflow without git stash: the half-finished work stays where it is.

Git worktrees →

Recovery

I deleted a branch with unmerged commits. Can I get it back?

Usually yes. The reflog records where HEAD has been, so find the deleted branch’s tip commit there and create a new branch at it.

git reflog
git switch -c feature/pricing <sha>
git log --oneline

This works because deleting a branch removes a pointer, not the commits. Unreferenced commits survive until Git garbage-collects them, so recover sooner rather than later.

Lab: recover a deleted branch →

How do I find the commit that introduced a bug?

git bisect runs a binary search over history: you mark a known-good and a known-bad commit, test what it checks out, and it halves the range each time.

git bisect start
git bisect bad
git bisect good <sha>
git bisect reset

Bisect checks out commits with HEAD detached. That is expected, not a problem to fix.

Lab: bisect a regression →

Merging & rebasing

What is git rebase?

Searched as what is git rebase

Rebasing takes a series of commits and replays them onto a different base, producing a new series with the same changes and different commit IDs. Everything powerful and everything dangerous about it follows from that one fact.

git rebase main
git rebase -i HEAD~3

Rebasing does not move commits; it creates new ones. On a branch someone else has pulled, that leaves their history and yours no longer sharing commits.

Git rebase explained →

What do the conflict markers in a merge conflict mean?

Everything between <<<<<<< HEAD and ======= is your side, the branch you are on. Everything between ======= and >>>>>>> is the incoming side. Git has marked the region it cannot decide.

git mergetool
git merge --abort   # start the resolution over

Resolving means writing what the code should do and proving it with a test, then removing every marker line. A tool that makes it easy to pick a side quickly can make it easier to pick the wrong one.

Resolving merge conflicts →

How do I stop resolving the same conflict on every rebase?

Turn on git rerere. It records how you resolved a conflict and replays that resolution automatically the next time the same conflict appears.

git config --global rerere.enabled true

It replays your earlier decision, so a resolution recorded wrongly is replayed wrongly. Review what it applies.

Git rerere →

gh CLI & API

Why does gh api --paginate --slurp --jq ‘length’ return the wrong count?

Searched as gh api --paginate --slurp behavior

Because --slurp wraps all pages in one outer array with one element per page, so length counts pages, not items. Flatten first with --jq ‘add | length’.

gh api repos/OWNER/REPO/issues --paginate --slurp --jq 'add | length'
gh api repos/OWNER/REPO/issues --paginate --jq '.[].number'

The second form needs no --slurp because .[] is applied per page. Leaving --slurp out of a whole-array filter is the version that produces silently wrong answers rather than an error.

gh api →

Why does gh api only return 30 results?

Because without --paginate you get one page. With it, gh follows the Link headers until there are no more pages, so the result is complete.

gh api repos/OWNER/REPO/issues --paginate

In GraphQL, --paginate follows cursors only if the query itself declares $endCursor and requests pageInfo.

gh api →

Actions security

What permissions should GITHUB_TOKEN have in a workflow?

Declare them explicitly and grant only what the job does. For a test job that reads the repository, permissions: contents: read is the baseline, because naming one scope sets every other scope to none.

permissions:
  contents: read

The token is minted at the start of a run and revoked at the end. Scopes such as actions: write are what a compromised step would use.

Least-privilege permissions →

Should I pin GitHub Actions to a commit SHA?

Yes for anything you do not control. A tag is a mutable pointer and can be moved to different code; a full commit SHA cannot. Dependabot understands SHA pins and raises pull requests that update them.

uses: actions/checkout@<full-40-char-sha>  # v4.2.2

A pinned SHA guarantees the code will not change. It does not say the code was safe, and an action that downloads a binary at run time is not pinned by its SHA.

Pinning actions →

How do I stop storing long-lived cloud keys in GitHub secrets?

Use OIDC. The workflow asks GitHub for a short-lived token that describes what is running, the cloud provider validates it against your trust policy, and issues its own short-lived credentials. Nothing long-lived is stored.

permissions:
  id-token: write
  contents: read

A short-lived token with an over-broad cloud role is still over-broad. The trust policy conditions are the part that has to be right.

OIDC in GitHub Actions →

Policy & access

"For security reasons, you cannot change the visibility of a fork." Why not?

Searched as for security reasons, you cannot change the visibility of a fork.

A fork shares its parent’s object storage and belongs to the parent’s fork network, so its visibility follows the parent’s. GitHub will not let the two diverge, because a private parent’s objects could otherwise become reachable through a public fork.

git clone --mirror https://github.com/OWNER/FORK.git
git push --mirror https://github.com/OWNER/NEW-REPO.git

To publish work that started as a fork, push the history into a new repository. Detaching a fork from its network is a GitHub Support request, not a setting.

Visibility and forking policies →

Why is CODEOWNERS requesting the wrong reviewer?

Because matches do not accumulate: for any given file, only the last matching line applies. A catch-all * at the bottom therefore owns everything and silently disables every rule above it.

# order general to specific
*        @core-team
/docs/   @docs-team

CODEOWNERS only requests review. Making owner review mandatory is a separate branch protection or ruleset setting.

CODEOWNERS →

Rulesets or branch protection — what is the difference?

Rulesets are named, layerable policies that a contributor can read, and they can target tags as well as branches. Classic branch protection is one rule per branch pattern, visible only to administrators.

Rule availability varies by plan: organisation-level rulesets targeting many repositories need an Enterprise plan. Rulesets also record what they evaluated, which branch protection does not.

Repository rulesets →

What do GitHub fine-grained personal access tokens change?

Searched as github fine grained tokens

Fine-grained personal access tokens split access into three independent choices: which resource owner the token acts for, which repositories it can touch, and which permissions it carries. Scope is no longer one coarse list.

They do not yet cover everything classic tokens do. One token cannot reach more than one organisation, and some APIs remain out of reach.

Fine-grained tokens →

The wording in each Searched as line is a real query string from this site’s Search Console property, for the 90 days from 23 June to 21 September 2026. Nothing here is a hypothetical question written to fill a page: the phrasing is what people actually typed, including the punctuation of a pasted error message.

That period is not typed into this page. It is read at build time from the report the queries came from, so it cannot drift away from the data behind it: pull Search Console again and the sentence above updates itself. This copy was last built from a report pulled on 24 September 2026.

Answers are taken from the lesson linked beside them, where the commands were run before publication. When GitHub changes something, the lesson is what gets corrected — so the lesson is the version to trust, and the answer here is the short form of it.

If you know the symptom but not the question

Section titled “If you know the symptom but not the question”

The same curriculum is published as an MIT-licensed MCP server, so a coding agent can search the lessons, read one, plan a recovery or review a workflow without scraping anything. It runs locally over stdio, and in remote mode it registers no tool that touches your repository.