문제

다음과 같은 것처럼 보이는 Git 저장소가 있습니다.

A -> B -> C -> D -> HEAD

나는 지점의 머리가 A를 가리키기를 원합니다. 즉, B, C, D를 원하고 머리가 사라지고 A와 동의어가되기를 원합니다. A와 동의어가되기를 원합니다.

Rebase (사이에 변경 사항을 추진했기 때문에 적용되지 않음) 또는 되돌릴 수있는 것처럼 들립니다. 그러나 여러 커밋을 어떻게 되돌리나요? 한 번에 하나씩 되돌아가나요? 주문이 중요합니까?

도움이 되었습니까?

해결책

내가 댓글로 쓴 것을 확장합니다

일반적인 규칙은 누군가가 자신의 작업을 기반으로했을 수도 있기 때문에 출판 한 역사를 다시 쓰지 말아야한다는 것입니다. 역사를 다시 쓰면 (변경), 변경 사항을 병합하고 업데이트하는 데 문제가 발생합니다.

따라서 해결책은 a를 만드는 것입니다 새로운 커밋 어느 변경 사항을 역전시킵니다 당신이 제거하고 싶어. 당신은 이것을 사용하여 할 수 있습니다 git 되돌립니다 명령.

다음과 같은 상황이 있습니다.

A <-- B  <-- C <-- D                                               <-- master <-- HEAD

(여기서 화살표는 포인터의 방향을 나타냅니다. 커밋의 경우 "부모"참조, Branch Head (Branch Ref)의 경우 상단 커밋 및 헤드 참조의 경우 브랜치 이름)를 나타냅니다.

만들어야 할 것은 다음과 같습니다.

A <-- B  <-- C <-- D <-- [(BCD)^-1]                   <-- master <-- HEAD

[(bcd)^-1]은 커밋 B, C, D. 수학이 우리에게 (bcd)^-1 = d^-1 c^-1 b^-1을 알려주는 커밋을 의미합니다. 다음 명령을 사용하여 필요한 상황을 얻을 수 있습니다.

$ git revert --no-commit D
$ git revert --no-commit C
$ git revert --no-commit B
$ git commit -m "the commit message"

대체 솔루션이 될 것입니다 점검 내용물 Commit a, 그리고이 상태를 커밋합니다.

$ git checkout -f A -- .
$ git commit -a

그런 다음 다음 상황이 있습니다.

A <-- B  <-- C <-- D <-- A'                       <-- master <-- HEAD

커밋 A '는 커밋 A와 동일한 내용을 가지고 있지만 다른 커밋 (커밋 메시지, 부모, 커밋 날짜)입니다.

그만큼 찰스 베일리 (Charles Bailey)가 수정 한 Jeff Ferland의 솔루션 같은 아이디어를 바탕으로하지만 사용합니다 git 재설정:

$ git reset --hard A
$ git reset --soft @{1}  # (or ORIG_HEAD), which is D
$ git commit

다른 팁

그렇게하려면 사용하면됩니다 돌아가는 것 명령, 반복하려는 커밋 범위를 지정합니다.

예제를 고려하면이 작업을 수행해야합니다 (Branch 'Master'에 있다고 가정) :

git revert master~3..master

이로 인해 B, C 및 D의 역 커밋 (이 커밋이 도입 한 변경 사항을 실행 취소 할 것임을 의미 함)으로 현지에서 새로운 커밋이 발생합니다.

A <- B <- C <- D <- BCD' <- HEAD

내가 유용하다고 생각한 깨끗한 방법

git revert --no-commit HEAD~3..

이 명령은 하나의 커밋만으로 마지막 3 커밋을 되돌립니다.

또한 역사를 다시 쓰지 않습니다.

Jakub의 답변과 마찬가지로,이를 통해 리버드를 쉽게 선택할 수 있습니다.

# revert all commits from B to HEAD, inclusively
$ git revert --no-commit B..HEAD  
$ git commit -m 'message'
git reset --hard a
git reset --mixed d
git commit

그것은 그들 모두에게 한 번에 되돌아 갈 것입니다. 좋은 커밋 메시지를 제공하십시오.

먼저 작업 사본이 수정되지 않았는지 확인하십시오. 그 다음에:

git diff HEAD commit_sha_you_want_to_revert_to | git apply

그리고 그냥 커밋하십시오. 되돌릴 이유를 문서화하는 것을 잊지 마십시오.

나는이 질문에 대답 할 수 없을 정도로 좌절했다. 다른 모든 질문은 올바르게 되돌리고 역사를 보존하는 방법과 관련이 있습니다. 이 질문은 말합니다 "나는 지점의 머리가 A를 가리키기를 원한다. 즉, 나는 b, c, d를 원한다. 사라지다 그리고 나는 머리가 A와 동의어가되기를 원합니다. "

git checkout <branch_name>
git reset --hard <commit Hash for A>
git push -f

나는 Jakub의 게시물을 많이 읽었지만 회사의 어떤 사람 (풀 레퍼스가없는 "테스트"지점을 밀어 붙일 수있는 액세스 권한이있는 5 명의 나쁜 커밋처럼 5 번의 커밋을 한 실수를 고치고 수정하려고 노력했습니다. 뿐만 아니라 한두 번의 풀 요청이 허용되었으며, 이제는 나빴습니다. 그래서 나는 그것을 잊어 버렸습니다. 나는 마지막 좋은 커밋 (ABC1234)을 발견하고 기본 스크립트를 실행했습니다.

git checkout testing
git reset --hard abc1234
git push -f

나는이 저장소에서 일하는 다른 5 명의 선수들에게 지난 몇 시간 동안의 변화를 더 잘 기록하고 최신 테스트에서 닦아/개조했다고 말했다. 이야기의 끝.

이것은 Jakub의 답변에 제공된 솔루션 중 하나의 확장입니다.

나는 롤백에 필요한 커밋이 다소 복잡한 상황에 직면했으며, 몇 가지 커밋이 합병 커밋이되었으며, 재 작성 이력을 피해야했습니다. 나는 일련의 것을 사용할 수 없었습니다 git revert 결국 반전 변경 사이의 충돌이 추가 되었기 때문에 명령. 다음 단계를 사용했습니다.

먼저, 지점 끝에 머리를 떠나는 동안 대상 커밋의 내용을 확인하십시오.

$ git checkout -f <target-commit> -- .

( - 확인하십시오 <target-commit> 파일이 아닌 커밋으로 해석됩니다. . 현재 디렉토리를 나타냅니다.)

그런 다음 롤백중인 커밋에 추가 된 파일을 결정하므로 삭제해야합니다.

$ git diff --name-status --cached <target-commit>

추가 된 파일은 줄의 시작 부분에 "A"와 함께 표시되어야하며 다른 차이점은 없어야합니다. 이제 파일을 제거 해야하는 경우 제거를 위해이 파일을 준비하십시오.

$ git rm <filespec>[ <filespec> ...]

마지막으로 복귀를 저지르십시오.

$ git commit -m 'revert to <target-commit>'

원하는 경우 원하는 상태로 돌아 왔는지 확인하십시오.

$git diff <target-commit> <current-commit>

차이가 없어야합니다.

공유 저장소에서 커밋 그룹을 되돌리는 쉬운 방법 (사람들이 사용하고 역사를 보존하려는)은 사용하는 것입니다. git revert git과 함께 rev-list. 후자는 커밋 목록을 제공 할 것입니다.

그렇게 할 두 가지 방법이 있습니다. 반복을 원한다면 단일 커밋 용도로 여러 커밋을 사용하십시오.

for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert -n $i; done

이것은 필요한 커밋 그룹을 되돌릴 것이지만, 작업 트리에 모든 변경 사항을 남겨두면 평소와 같이 커밋해야합니다.

또 다른 옵션은 회복 된 변경 당 단일 커밋을 갖는 것입니다.

for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert --no-edit -s $i; done

예를 들어, 커밋 트리가있는 경우

 o---o---o---o---o---o--->    
fff eee ddd ccc bbb aaa

변경 사항을 되돌립니다 eee 에게 BBB, 운영

for i in `git rev-list eee^..bbb`; do git revert --no-edit -s $i; done

그 중 어느 것도 나를 위해 일하지 않았으므로, 나는 3 번의 커밋을 되돌려 놓았습니다 (마지막 세 커밋).

git revert HEAD
git revert HEAD~2
git revert HEAD~4
git rebase -i HEAD~3 # pick, squash, squash

매력처럼 일했습니다 :)

제 생각에는 매우 쉽고 깨끗한 방법은 다음과 같습니다.

다시 돌아 가십시오

git checkout -f A

포인트 마스터의 헤드는 현재 상태로 향합니다

git symbolic-ref HEAD refs/heads/master

저장

git commit

기능의 커밋을 일시적으로 되돌려면 일련의 다음 명령을 사용할 수 있습니다.

작동 방식은 다음과 같습니다

git log -pretty = oneline | grep 'feaction_name'| 컷 -d ''-f1 | Xargs -n1 git revert -no -edit

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top