git-update-ref
Update the object name stored in a ref
TLDR
Delete a ref, useful for soft resetting the first commit
Update ref with a message
SYNOPSIS
git update-ref [options] [-m reason] (refname newvalue [oldvalue])
git update-ref [options] --delete [--no-verify] refname [oldvalue]
git update-ref [options] --stdin [-z]
PARAMETERS
-d, --delete
Delete the named ref if it exists; optionally verify oldvalue.
--exists
Check if ref exists and exit successfully if true, else fail.
--create-reflog
Create reflog for ref if it doesn't already exist.
--force-create-reflog
Force reflog creation even if ref already has one.
--no-deref
Update refname directly without dereferencing symbolic refs.
--verify [=mode]
Strictly verify ref matches oldvalue; modes: warn, loose, exact.
--no-verify
Bypass pre- and post-update hooks during ref update.
-m reason
Record reason in reflog entry for the update.
-z
Use NUL as delimiter for refname, newvalue, oldvalue (stdin mode).
--stdin
Read update commands from stdin, one per line or NUL-delimited.
--quiet, -q
Suppress progress output and error messages.
--refs prefix
Restrict refs to those under the specified prefix.
DESCRIPTION
git update-ref is a low-level plumbing command in Git for safely updating object references such as branches, tags, or notes. It performs atomic updates, ensuring the reference either points to the specified new value or remains unchanged on failure, preventing race conditions in concurrent environments.
This command does not update the working tree, index, or run hooks by default (unless options specify), making it ideal for scripts and internal Git porcelain commands like git branch or git commit. Users typically invoke it indirectly rather than directly.
Key uses include moving a ref to a new commit SHA-1, deleting refs, or verifying existence. It supports conditional updates by checking an expected old value, enhancing safety. Reflogs are not created automatically to avoid side effects, but can be enabled with --create-reflog.
Unlike higher-level commands, it handles packed refs and loose refs transparently, but requires careful handling of refnames (e.g., refs/heads/master). Misuse can lead to ref corruption, so it's recommended for advanced scripting only.
CAVEATS
Plumbing command; misuse can corrupt refs or cause inconsistencies. Avoid direct use outside scripts. Does not handle symbolic refs by default (use --no-deref). Atomicity assumes single repository access.
COMMON EXAMPLES
Update branch: git update-ref refs/heads/master HEAD~1
Delete tag: git update-ref -d refs/tags/v1.0
Conditional update: git update-ref refs/heads/master newcommit oldcommit
STDIN MODE
For batch updates: echo 'refs/heads/master newsha oldsha' | git update-ref --stdin
Supports multiple lines or -z for NUL-delimited input.
HISTORY
Introduced in Git 1.5.3 (2007) as core plumbing for safe ref manipulation. Evolved with options like --stdin in Git 1.7.0+ for batch operations. Remains essential for Git's internal ref handling in modern versions.
SEE ALSO
git-branch(1), git-tag(1), git-reflog(1), git-symbolic-ref(1), git-check-ref-format(1)


