본문 중간의 쿠팡 추천 상품 구매시 쿠팡 파트너스에서 일정액의 수수료를 제공받습니다.

git update-ref는 branch나 tag 같은 Git ref에 저장된 object ID를 안전하게 바꾸는 저수준 명령입니다. 일반 작업에서는 git branch, git tag, git reset 같은 상위 명령을 쓰는 편이 자연스럽지만, 스크립트에서 ref 값을 검증한 뒤 갱신해야 할 때는 git update-ref의 원자적 갱신 기능이 중요합니다.
2026년 8월 10일 기준 Git 공식 문서에서 git-update-ref 매뉴얼은 Git 2.53.0에서 마지막으로 갱신되었고, Git 2.54.0부터 2.55.0까지 내용 변경이 없습니다. 공식 설명의 핵심은 단순합니다. 새 object ID를 ref에 저장하되, 필요하면 현재 값이 기대한 old object ID와 일치하는지 먼저 확인합니다.
무엇을 바꾸는 명령인가
Git의 ref는 commit, tag object 같은 object ID를 가리키는 이름입니다. 예를 들어 refs/heads/main은 보통 main branch의 최신 commit을 가리키고, HEAD는 현재 작업 위치를 나타내는 symbolic ref로 쓰이는 경우가 많습니다.
git update-ref <ref> <new-oid> 형태는 해당 ref가 새 object ID를 가리키도록 저장합니다. HEAD처럼 symbolic ref를 넘기면 기본적으로 symbolic ref가 가리키는 실제 ref를 따라가서 갱신합니다. 반대로 --no-deref를 붙이면 symbolic ref를 따라가지 않고 지정한 ref 자체를 대상으로 삼습니다.

왜 old object ID를 함께 쓰나
git update-ref의 실무상 핵심은 세 번째 인자인 <old-oid>입니다. 세 인자 형태인 git update-ref <ref> <new-oid> <old-oid>는 현재 ref 값이 old object ID와 일치할 때만 새 값으로 바꿉니다.
이 방식은 스크립트에서 특히 중요합니다. 스크립트가 현재 ref 값을 읽은 뒤 새 값을 계산하는 사이에 다른 작업이 같은 ref를 바꿨다면, old object ID 검증이 실패하면서 잘못된 덮어쓰기를 막을 수 있습니다. Git 공식 문서는 ref를 새로 만들 때 기존 ref가 없어야 함을 보장하려면 old object ID에 40개의 0 또는 빈 문자열을 지정할 수 있다고 설명합니다.
old=$(git rev-parse refs/heads/topic)
new=$(git rev-parse HEAD)
git update-ref refs/heads/topic "$new" "$old"

삭제와 reflog 기록은 어떻게 처리하나
ref를 삭제하려면 -d를 사용합니다. 이때도 old object ID를 함께 주면 삭제 전에 현재 값이 기대값과 맞는지 확인할 수 있습니다.
git update-ref -d refs/heads/topic "$old"
변경 이유를 reflog에 남기고 싶다면 -m <reason>을 붙입니다. 공식 문서에 따르면 core.logAllRefUpdates가 켜져 있거나 해당 ref의 log 파일이 있는 경우, Git은 ref 변경 로그에 이전 값, 새 값, committer 정보, 선택적으로 -m 메시지를 기록합니다.
git update-ref -m "move topic to reviewed commit" refs/heads/topic "$new" "$old"
--stdin은 언제 필요한가
여러 ref를 함께 갱신해야 한다면 --stdin 형식을 검토합니다. 공식 문서는 update, create, delete, verify 같은 명령을 표준 입력으로 전달할 수 있고, start, prepare, commit, abort로 transaction을 구성할 수 있다고 설명합니다.
중요한 차이는 실패 처리입니다. 모든 ref를 동시에 lock하고 old object ID 조건이 맞으면 queued update가 수행됩니다. 조건이 맞지 않거나 lock을 잡을 수 없으면 전체 변경이 수행되지 않습니다. 다만 공식 문서는 개별 ref 갱신은 원자적이지만, 동시에 읽는 독자가 여러 변경 중 일부 상태를 볼 수 있다는 점도 함께 명시합니다.
git update-ref --stdin <<'EOF'
start
update refs/heads/topic NEW_OID OLD_OID
update refs/tags/reviewed NEW_TAG_OID OLD_TAG_OID
prepare
commit
EOF

symbolic ref는 어떻게 구분하나
git update-ref는 일반 ref의 object ID 갱신에 초점이 있습니다. symbolic ref가 다른 ref를 가리키도록 만들거나 읽고 싶다면 git symbolic-ref가 더 직접적인 명령입니다. Git 공식 git-symbolic-ref 문서는 symbolic ref를 ref: refs/...로 시작하는 문자열을 저장한 일반 파일로 설명합니다.
따라서 branch pointer의 commit을 바꾸는 작업과, HEAD가 어느 branch를 가리키는지 바꾸는 작업은 구분해서 봐야 합니다. 전자는 git update-ref가 맞고, 후자는 보통 checkout, switch, 또는 git symbolic-ref의 영역입니다.
상위 명령 대신 직접 써도 될까
사람이 일반적으로 branch를 옮기거나 tag를 만들 때는 상위 명령을 먼저 쓰는 편이 안전합니다. git update-ref는 저수준 명령이라 의도를 더 직접적으로 표현하지만, 그만큼 잘못된 ref 이름이나 object ID를 넘겼을 때 repository 상태를 예상과 다르게 만들 수 있습니다.
| 목적 | 보통 먼저 볼 명령 | git update-ref가 맞는 경우 |
|---|---|---|
| 현재 branch 이동 | git reset, git switch |
스크립트에서 old object ID 검증 후 branch ref만 갱신할 때 |
| tag 생성 또는 변경 | git tag |
여러 ref를 transaction 형태로 함께 처리할 때 |
| symbolic ref 변경 | git symbolic-ref |
--stdin의 symref-* 명령까지 함께 다룰 때 |
| 변경 이력 확인 | git reflog |
-m으로 ref 변경 사유를 명시해 기록할 때 |
선택 기준
- 일반 사용자는 branch, tag, reset 같은 상위 명령을 먼저 선택합니다.
- 스크립트에서 ref 값을 직접 바꿔야 한다면 old object ID를 함께 넘깁니다.
- ref가 없어야 함을 보장하고 만들 때는 old object ID에 40개의
0또는 빈 문자열을 사용합니다. - 삭제도 무조건 실행하지 말고 가능하면 old object ID 검증을 함께 둡니다.
- 여러 ref를 묶어 처리해야 하면
--stdintransaction 흐름을 검토합니다. - symbolic ref 자체의 대상 변경은
git symbolic-ref와 역할을 비교합니다.
핵심은 git update-ref를 "ref 파일을 직접 고치는 명령"이 아니라 "기대값 검증과 lock을 거쳐 ref를 갱신하는 저수준 인터페이스"로 보는 것입니다. 사람이 한 번 실행하는 작업보다 자동화된 ref 갱신에서 가치가 더 큽니다.
FAQ
git update-ref HEAD <new-oid>는 HEAD 파일 자체를 바꾸나
기본적으로는 symbolic ref를 따라갑니다. HEAD가 refs/heads/main을 가리키고 있다면, 실제 갱신 대상은 그 branch ref가 됩니다. 지정한 ref 자체를 따라가지 않고 갱신하려면 --no-deref를 사용합니다.
old object ID를 생략해도 안전한가
두 인자 형태도 공식적으로 지원되지만, 현재 ref 값이 기대한 값인지 확인하지 않습니다. 다른 작업과 충돌할 가능성이 있는 스크립트라면 old object ID를 넣는 편이 안전합니다.
--batch-updates는 모든 실패를 부분 실패로 바꾸나
아닙니다. Git 공식 문서는 잘못된 사용자 입력처럼 개별 update의 거부는 부분 실패로 보고할 수 있지만, I/O 실패나 메모리 문제 같은 시스템 관련 오류는 전체 batch 실패가 된다고 설명합니다.
참고 문서
'프로그래밍 > Git, IDE, 툴 관련' 카테고리의 다른 글
| Git notes 사용법 (0) | 2026.08.16 |
|---|---|
| Git for-each-ref 사용법 (0) | 2026.08.13 |
| Git name-rev 사용법 (0) | 2026.08.05 |
| Git check-ref-format 사용법 (1) | 2026.08.02 |
| Git show-ref 사용법 (0) | 2026.07.31 |





