자식 분기를 원래 버전으로 재설정해야합니다.


439

나는 한동안은 안되었을 지점에서 실수로 일하고 있었기 때문에 적절한 이름을 부여하면서 그 지점을 벗어났습니다. 이제 원산지 버전 (github)에 있지 않아야했던 지점을 덮어 쓰고 싶습니다. 이 작업을 수행하는 쉬운 방법이 있습니까? 지점을 삭제 한 다음 추적 지점을 재설정하려고했지만 다시 작업중 인 버전을 제공합니다.



Git 2.23 (2019 년 8 월) : git switch -C mybranch origin/mybranch. 아래에서 편집 한 답변
VonC

답변:


814

아직 원점으로 푸시하지 않은 경우 다음을 사용하여 분기를 업스트림 분기로 재설정 할 수 있습니다 .

git checkout mybranch
git reset --hard origin/mybranch

(질문에 언급 한 것처럼 최신 커밋을 별도의 지점에서 참조해야합니다)

재설정 직후, 재설정 mybranch@{1}전의 이전 커밋을 참조하십시오.

그러나 이미 푸시 한 경우 다른 옵션 은 " git 브랜치 생성 및 원본을 업스트림 상태로 되돌리기 "를 참조하십시오 .


Git 2.23 (2019 년 8 월)을 사용하면 하나의 명령이 git switch됩니다.
즉:git switch -C mybranch origin/mybranch

C:\Users\vonc\git\git>git switch -C master origin/master
Reset branch 'master'
Branch 'master' set up to track remote branch 'master' from 'origin'.
Your branch is up to date with 'origin/master'.

그러면 인덱스와 작업 트리가 원하는대로 복원 git reset --hard됩니다.


Brad Herman이 언급 한 것처럼 a reset --hard새 파일을 제거하거나 수정 된 파일을 HEAD로 재설정합니다 .

실제로, "클린 슬레이트"에서 시작 git clean -f -d하기 위해 재설정 후에는 작업 트리가 방금 재설정 한 분기 와 정확히 동일한 작업 트리를 보장합니다 .


블로그 게시물 은 이러한 별칭을 제안합니다 ( master브랜치 전용이지만 별칭 을 적용 / 확장 할 수 있음).

[alias]
   resetorigin = !git fetch origin && git reset --hard origin/master && git clean -f -d
   resetupstream = !git fetch upstream && git reset --hard upstream/master && git clean -f -d

그런 다음 다음을 입력 할 수 있습니다.

git resetupstream

또는

git resetorigin

26
이것은 언 스테이지 / 스테이지 변경을 삭제합니다 (--hard에서)
Peter Ehrlich

5
git reset --hard origin/mybranch로컬 변경 사항에 신경 쓰지 않고 원본과 일치하는 깨끗한 사본을 원할 때 명령을 여러 번 사용했습니다 . 그러나 오늘은 효과가 없었습니다. 여전히 준비되지 않은 새로운 파일이 몇 개 있었고 git은 계속 HEAD에 있다고 약속했습니다. 에 대한 참고 git clean -f -d모든 새로운 파일을 닦아 내가 원하는하지 않았다 것을 해결했습니다.
Matthew Clark

@MatthewClark 예상됩니다 : stackoverflow.com/q/4327708/6309에
VonC

1
큰! 또한 여러 번 git reset --hard HEAD변경 사항을 무시하고 이전 커밋으로 되돌
리곤했습니다.

sourctree에서도 가능합니까?
Lonzak

20

이것이 일어난 일이라고 가정 :

# on branch master
vi buggy.py                 # you edit file
git add buggy.py            # stage file
git commit -m "Fix the bug" # commit
vi tests.py                 # edit another file but do not commit yet

그런 다음 잘못된 브랜치에서 변경을 수행한다는 것을 알고 있습니다.

git checkout -b mybranch    # you create the correct branch and switch to it

그러나 master여전히 커밋을 가리 킵니다. 당신은 그것이 전에 가리키는 곳을 가리 키기를 원합니다.

해결책

가장 쉬운 방법은 다음과 같습니다.

git branch --force master origin/master

다른 방법은 다음과 같습니다.

git checkout master
git reset --soft origin/master
git checkout mybranch

를 사용 reset --hard하면 커밋되지 않은 변경 사항이 손실됩니다 ( tests.py예제에서).


내 대답보다 안전 해 보인다;) +1
VonC

8

서버에 개인 저장소가 있고 정기적으로 rebase / force-push하기 때문에 다른 컴퓨터에서 로컬 지점을 자주 재설정해야합니다. 따라서 다음 분기 "catchup"이라는 별칭을 만들어 현재 분기에 대해이 작업을 수행 할 수 있습니다. 다른 답변과 달리이 별칭에는 하드 코딩 된 분기 이름이 없습니다.

꽉 잡아.

[alias]
  catchup = "!f(){ echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \"; read -r ans; if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)); else echo \"catchup aborted\"; fi }; f"

올바른 형식 (.gitconfig의 줄 바꿈에서는 작동하지 않음)은 다음과 같습니다.

"
!f(){
  echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \";
  read -r ans;
  if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then
    git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD));
  else
    echo \"catchup aborted\";
  fi
}; f
"
  • \\033[0;33m\\033[0m색상으로 현재의 지점과 상류을 강조위한 것입니다.
  • $(git symbolic-ref -q --short HEAD) 현재 지점 이름입니다
  • $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)) 현재 브랜치의 업스트림입니다.

재설정은 잠재적으로 위험한 호출이므로 (특히 --hard 옵션을 사용하면 커밋되지 않은 변경 내용을 잃게됩니다) 먼저 먼저 수행 할 작업을 알려줍니다. 예를 들어 qcpp / dev-container 라는 원격 으로 분기 dev-container 에 있고를 입력 하면 프롬프트가 표시됩니다.git catchup

dev-container를 qcpp / dev-container로 재설정 하시겠습니까? (Y / n)

그런 다음 y를 입력하거나 return 키를 누르면 재설정이 수행됩니다. 다른 것을 입력하면 재설정이 수행되지 않습니다.

매우 안전하고 프로그래밍 방식으로 비 단계적 / 커밋되지 않은 변경 내용의 손실을 방지하려면 diff-index 검사를 통해 위의 별칭을 추가로 포징 할 수 있습니다 .

필수 경고 : 다른 사람들이 작업을 수행 한 공용 저장소에서 작업 중이고이 별명이 필요한 경우 잘못된 작업을 수행하는 것 입니다.


1

나는 이것을 시도했지만 현재 지점을 원격 github 최신으로 재설정하지 않았다. 나는 구글 검색하고 https://itsyndicate.org/blog/how-to-use-git-force-pull-properly/

제안한

git fetch origin master
git reset --hard origin/master

v8 브랜치를 재설정하고 싶었습니다.

git fetch origin v8
git reset --hard origin/v8

그리고 그것은 효과가 있었다


fetch를 언급하는 것이 좋습니다. 나는 그것을하지 않고 한 번하고 모든 것을 2 년 전에 재설정했습니다 :)
Adam
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.