Move a branch tip without touching HEAD.
git update-ref atomically writes a value into a ref file (or packed-refs entry) and, when configured, appends a reflog line. It is how scripts move branch tips without going through checkout, reset, or commit.
A ref is just a file containing a SHA. update-ref does the equivalent of echo <sha> > .git/refs/... but with locking, optional compare-and-swap, reflog updates, and packed-refs awareness. HEAD is never moved as a side effect.
git update-ref [-m <reason>] [--create-reflog] [--no-deref]
<refname> <newvalue> [<oldvalue>]
git update-ref -d <refname> [<oldvalue>]
git update-ref --stdin [-z] # batch, transactional| Flag | What it does |
|---|---|
<refname> <newvalue> [<oldvalue>] | Set ref to newvalue; if oldvalue is given, fail unless it currently equals oldvalue (compare-and-swap). |
-d, --delete <ref> [<oldvalue>] | ⚠️ Delete the ref; with oldvalue, only delete if it still points there. |
-m <reason> | Reflog message to record alongside the update (only used if a reflog exists). |
--create-reflog | Force-create a reflog for this ref even if core.logAllRefUpdates would not. |
--no-deref | Operate on the symbolic ref itself, not its target (e.g. rewrite HEAD as a SHA). |
--stdin [-z] | Read multiple update/delete/create/verify commands and apply them in a single transaction. |
echo 'update refs/heads/main <new> <old>' | git update-ref --stdinecho 'create refs/heads/feat <sha>' | git update-ref --stdinecho 'delete refs/heads/old <sha>' | git update-ref --stdinecho 'verify refs/heads/main <sha>' | git update-ref --stdingit update-ref refs/heads/main <new_sha> <old_sha>git update-ref -d refs/heads/wipgit update-ref -m 'rebase: onto main' refs/heads/feat <new_sha>printf 'update refs/heads/a %s\nupdate refs/heads/b %s\n' $A $B | git update-ref --stdinHit each option, then Check answers. Score is recorded; Next is always open.