본문 바로가기
빌드노트 검색

빌드노트

origin URL을 바꿨는데 push만 이전 주소로 갈 때

origin의 일반 URL을 바꿔도 별도 pushurl이 남으면 push는 이전 주소를 사용한다. fetch URL과 모든 push URL을 따로 조회하고, 공유 URL로 합치거나 push 주소만 바꾸는 방법을 로컬 bare 저장소의 수신 ref로 확인한다.

git remote set-url origin …으로 주소를 바꿨는데 fetch는 새 주소를 쓰고 push는 이전 주소로 갈 수 있다. remote.origin.pushurl이 따로 남아 있으면 push는 그 값을 사용한다. fetch 주소가 바뀌었다는 것만으로 push 대상까지 바뀌었다고 판단하면 안 된다.

origin의 fetch URL과 push URL을 따로 읽는다

Git이 설치된 터미널에서 문제가 있는 저장소를 연다. 여기서는 origin을 명시해 push하는 경우를 다룬다. 다른 remote를 쓴다면 아래 이름도 바꾼다. 먼저 fetch URL과 모든 push URL을 차례로 조회한다. 이 두 명령은 원격에 접속하거나 커밋을 전송하지 않는다.

git remote get-url --all origin
git remote get-url --push --all origin

로컬 재현에서 첫 명령은 ../new.git, 두 번째는 ../old.git을 출력했다. origin이라는 이름은 같지만 읽는 곳과 쓰는 곳이 갈라진 상태다. 두 경로는 실험용 bare 저장소를 가리키며, 실제 저장소에서는 자신의 HTTPS·SSH 주소나 로컬 경로가 나온다.

--push는 push에 쓸 URL을 조회하고, --all은 등록된 URL을 모두 보여 준다. --all을 빼면 첫 주소만 보여 추가 전송 대상을 놓칠 수 있다. URL 재작성 설정인 insteadOf와 pushInsteadOf도 이 조회에 반영된다. git-remote의 get-url 설명 (새 탭에서 열림)

두 결과가 다르면 별도 push URL이 어디에 저장됐는지 확인한다.

git config --show-origin --get-all remote.origin.pushurl

이번 재현의 출력은 file:.git/config 뒤에 탭으로 구분된 ../old.git이었다. 현재 저장소 설정 파일에 이전 주소가 남아 있다는 뜻이다. 이 명령은 저장된 원래 값을 보여 주므로 URL 재작성을 반영하는 get-url과 문자열이 다를 수 있다. 출력이 없고 종료 코드가 1이면 해당 키가 없는 경우다. push URL 조회도 이미 원하는 주소라면 이 글의 pushurl 원인으로 단정하지 않는다. 설정값과 출처 조회 (새 탭에서 열림)

같은 주소를 쓸지, push 주소를 따로 둘지 정한다

fetch와 push를 모두 새 주소로 옮기려는 상황이라면 별도 pushurl을 없애는 방법이 있다. fetch URL이 원하는 주소 하나이고, 삭제할 push URL이 모두 방금 확인한 .git/config에 있을 때 다음 명령으로 이 저장소의 push URL 설정을 전부 지운다.

git config --local --unset-all remote.origin.pushurl

성공한 뒤 앞의 get-url 두 명령을 다시 실행한다. 실험에서는 둘 다 ../new.git을 출력했다. 별도 pushurl이 없으므로 push도 remote.origin.url을 사용한 것이다. --local은 현재 저장소 설정만 수정한다. 다른 파일에서 읽어 온 값은 이 명령으로 지워지지 않으므로, 명령이 실패하거나 이전 주소가 다시 나오면 출처부터 다시 확인한다. 설정 파일의 읽기·쓰기 범위 (새 탭에서 열림)

반대로 fetch와 push에 서로 다른 접속 주소를 유지해야 한다면 pushurl을 원하는 값으로 바꾼다. 다음은 push URL이 하나일 때의 수정이다. ../new.git은 실제로 검증한 로컬 입력이며, 자신의 저장소에서는 따옴표 안에 원하는 push URL을 넣어 바꾼다.

git remote set-url --push origin '../new.git'
git remote get-url --push --all origin

첫 명령이 성공하면 두 번째 조회가 새 주소 하나를 보여야 한다. --add를 붙이면 주소를 교체하지 않고 추가하므로, 이전 주소로 보내는 일을 멈추려는 상황에서는 사용하지 않는다. push URL이 여러 개이고 하나만 남기려는 경우에는 출처를 확인하고 위의 로컬 값 전체 삭제를 먼저 수행한 뒤 원하는 push URL을 설정한다. git-remote의 set-url 설명 (새 탭에서 열림)

조회한 주소가 실제 수신 저장소와 일치했다

Windows의 Git 2.45.1.windows.1, PowerShell 7.6.6에서 새 bare 저장소 old.git, new.git과 clone 하나로 비교했다. 주소 선택을 구별하기 위해 두 bare 저장소를 독립적으로 만들고 같은 시작 커밋을 넣었다. 각 조건에서 합성 커밋을 push한 뒤 두 저장소의 브랜치 참조(ref)가 실제로 생겼는지 확인했다.

  • 별도 pushurl 없이 일반 URL을 새 주소로 바꾸자 check-control ref는 new.git에만 생겼다.
  • pushurl을 이전 주소로 두고 일반 URL만 새 주소로 바꾸자 fetch는 new.git의 커밋을 읽었지만, push한 check-problem ref는 old.git에만 생겼다.
  • 단일 push URL을 새 주소로 고친 뒤 check-fixed ref는 new.git에만 생겼다. 별도 push URL을 모두 지운 뒤의 check-shared ref도 new.git에만 생겼다.

push URL을 ../old.git, ../new.git 두 개로 등록한 조건도 비교했다. get-url --push origin은 첫 주소만 출력했지만, --all을 붙이면 두 주소가 나왔다. 실제 push에서는 check-multi ref가 두 저장소에 같은 커밋으로 생겼다. 공식 문서도 여러 push URL을 모두 전송 대상으로 설명한다. 하나가 실패하면 다음 주소를 고르는 예비 주소 목록으로 보면 안 된다. remote의 pushurl 설정 (새 탭에서 열림)

이 Git 버전에서 push URL 두 개를 그대로 둔 채 단순 set-url --push 수정도 시도했다. remote.origin.pushurl has multiple values 경고와 함께 종료 코드 128로 실패했고 두 값은 그대로 남았다. 따라서 단일 URL 수정 명령이 여러 값을 한 번에 정리해 준다고 가정하지 말고, 수정 뒤 전체 목록을 다시 읽어야 한다.

실험은 로컬 파일 전송으로 주소 선택과 수신 ref를 확인한 범위다. HTTPS·SSH 인증, 서버 권한, 여러 대상 중 일부가 실패할 때의 처리나 원자성은 검증하지 않았다. 실제 구성에서는 한 remote의 fetch·push 주소가 같은 저장소를 가리켜야 한다. upstream에서 받고 별도 fork로 보내려는 목적이라면 두 remote로 나누라는 것이 Git 공식 문서의 안내 (새 탭에서 열림)다.

← 전체 글 보기