마스터하기로 커밋한 마지막 몇 개의 커밋을 새 분기로 옮기고 해당 커밋이 수행되기 전으로 마스터를 되돌리고 싶습니다. 불행히도 내 Git-fu가 아직 충분히 강력하지 않습니다. 도움이 필요하십니까?
즉 내가 어떻게 갈 수 있습니까?
master A - B - C - D - E
이에?
newbranch C - D - E / master A - B
질문자 :Mark A. Nicolosi
마스터하기로 커밋한 마지막 몇 개의 커밋을 새 분기로 옮기고 해당 커밋이 수행되기 전으로 마스터를 되돌리고 싶습니다. 불행히도 내 Git-fu가 아직 충분히 강력하지 않습니다. 도움이 필요하십니까?
즉 내가 어떻게 갈 수 있습니까?
master A - B - C - D - E
이에?
newbranch C - D - E / master A - B
답변자 : Community Wiki
커밋을 기존 분기 로 이동하려면 다음과 같이 표시됩니다.
git checkout existingbranch git merge master git checkout master git reset --hard HEAD~3 # Go back 3 commits. You *will* lose uncommitted work. git checkout existingbranch
git stash
사용하여 이 작업을 수행하기 전에 커밋되지 않은 편집 내용을 stash에 저장할 수 있습니다. git stash pop
사용하여 숨겨진 커밋되지 않은 편집을 검색할 수 있습니다.
경고: git branch newbranch
로 새 분기를 생성하기 때문에 작동합니다. 커밋을 기존 분기 로 이동하려면 git reset --hard HEAD~3
실행하기 전에 변경 사항을 기존 분기로 병합해야 합니다( 위의 기존 분기로 이동 참조). 변경 사항을 먼저 병합하지 않으면 손실됩니다.
관련된 다른 상황이 없는 한 분기 및 롤백을 통해 쉽게 수행할 수 있습니다.
# Note: Any changes not committed will be lost. git branch newbranch # Create a new branch, saving the desired commits git reset --hard HEAD~3 # Move master back by 3 commits (Make sure you know how many commits you need to go back) git checkout newbranch # Go to the new branch that still has the desired commits
그러나 얼마나 많은 커밋을 되돌릴 것인지 확인하십시오. 또는 HEAD~3
대신 마스터 (/current) 분기에서 "되돌리기"하려는 커밋(또는 origin/master 같은 참조)의 해시를 제공하면 됩니다. 예:
git reset --hard a1b2c3d4
*1 master 브랜치의 커밋만 "잃어버릴" 것이지만 걱정하지 마세요. 해당 커밋은 newbranch에 있을 것입니다!
경고: Git 버전 2.0 이상을 사용하면 나중에 master
) 분기에 새 분기를 git rebase
하는 경우 이월된 커밋을 잃지 않기 위해 rebase 중에 --no-fork-point
옵션이 필요할 수 있습니다. branch.autosetuprebase always
설정하면 이 가능성이 높아집니다. 자세한 내용은 John Mellor의 답변 을 참조하십시오.
답변자 : Ryan Lundy
그것이 작동하는 이유를 궁금해하는 사람들을 위해(처음처럼):
C로 돌아가서 D와 E를 새 분기로 이동하려고 합니다. 처음에는 다음과 같습니다.
ABCDE (HEAD) ↑ master
git branch newBranch
이후:
newBranch ↓ ABCDE (HEAD) ↑ master
git reset --hard HEAD~2
:
newBranch ↓ ABCDE (HEAD) ↑ master
분기는 포인터일 뿐이므로 마스터 는 마지막 커밋을 가리켰습니다. newBranch 를 만들 때 마지막 커밋에 대한 새 포인터를 만들었습니다. 그런 다음 git reset
을 사용하여 마스터 포인터를 두 커밋 뒤로 옮겼습니다. 그러나 newBranch를 이동하지 않았기 때문에 원래 수행했던 커밋을 여전히 가리킵니다.
답변자 : Ivan
이 경우에는 sykora에 의해 노출되는 방법이 최선의 선택입니다. 그러나 때로는 가장 쉬운 방법이 아니며 일반적인 방법이 아닙니다. 일반적인 방법의 경우 git cherry-pick를 사용하십시오 .
OP가 원하는 것을 달성하기 위해 2단계 프로세스:
newbranch
원하는 마스터의 커밋 기록실행하다
git checkout master git log
newbranch
원하는 커밋(예: 3)의 해시를 확인하세요. 여기에서 나는 다음을 사용할 것이다:
C 커밋: 9aa1233
D 커밋: 453ac3d
전자 커밋: 612ecb3
참고: 처음 7자 또는 전체 커밋 해시를 사용할 수 있습니다.
newbranch
git checkout newbranch git cherry-pick 612ecb3 git cherry-pick 453ac3d git cherry-pick 9aa1233
git checkout newbranch git cherry-pick 612ecb3~1..9aa1233
git cherry-pick은 이 세 가지 커밋을 newbranch에 적용합니다.
답변자 : John Mellor
다음과 같이 하지 마십시오.
git branch -t newbranch git reset --hard HEAD~3 git checkout newbranch
git rebase
(또는 git pull --rebase
)를 실행할 때 newbranch
에서 자동으로 삭제됩니다! (아래 설명 참조)
대신 다음을 수행하십시오.
git reset --keep HEAD~3 git checkout -t -b newbranch git cherry-pick ..HEAD@{2}
--keep
은 --hard
와 비슷하지만 커밋되지 않은 변경 사항을 버리는 것보다 실패하므로 더 안전합니다).newbranch
분기합니다.newbranch
다시 선택합니다. 더 이상 브랜치에서 참조하지 않기 때문에 git의 reflog 를 사용하여 이를 수행합니다. HEAD@{2}
HEAD
가 2개 작업 전에 참조하는 데 사용한 커밋입니다 newbranch
및 2. used git reset
3개의 커밋을 삭제하도록 git reset
경고: reflog는 기본적으로 활성화되어 있지만 수동으로 비활성화한 경우(예: "bare" git 저장소를 사용하여) git reset --keep HEAD~3
.
reflog에 의존하지 않는 대안은 다음과 같습니다.
# newbranch will omit the 3 most recent commits. git checkout -b newbranch HEAD~3 git branch --set-upstream-to=oldbranch # Cherry-picks the extra commits from oldbranch. git cherry-pick ..oldbranch # Discards the 3 most recent commits from oldbranch. git branch --force oldbranch oldbranch~3
(원하는 경우 @{-1}
- 이전에 체크아웃한 분기 - oldbranch
).
git rebase
가 첫 번째 예제 이후에 3개의 커밋을 버리는 이유는 무엇입니까? 인수가 없는 git rebase
--fork-point
옵션은 로컬 reflog를 사용하여 강제로 푸시되는 업스트림 분기에 대해 강건해지려고 합니다.
M1, M2, M3 커밋이 포함되어 있을 때 origin/master에서 분기한 다음 직접 세 번 커밋했다고 가정합니다.
M1--M2--M3 <-- origin/master \ T1--T2--T3 <-- topic
그러나 누군가 M2를 제거하기 위해 Origin/master를 강제로 푸시하여 기록을 다시 작성합니다.
M1--M3' <-- origin/master \ M2--M3--T1--T2--T3 <-- topic
로컬 reflog를 사용하여 git rebase
는 원본/마스터 브랜치의 이전 구현에서 분기되어 M2 및 M3 커밋이 실제로 토픽 브랜치의 일부가 아님을 확인할 수 있습니다. 따라서 M2가 업스트림 분기에서 제거되었으므로 주제 분기가 다시 기반으로 지정되면 더 이상 주제 분기에서 M2를 원하지 않는다고 합리적으로 가정합니다.
M1--M3' <-- origin/master \ T1'--T2'--T3' <-- topic (rebased)
이 동작은 이해가 되며 일반적으로 리베이스할 때 올바른 방법입니다.
따라서 다음 명령이 실패하는 이유:
git branch -t newbranch git reset --hard HEAD~3 git checkout newbranch
reflog를 잘못된 상태로 두기 때문입니다. Git은 newbranch
가 3개의 커밋을 포함하는 개정판에서 업스트림 분기를 분기한 reset --hard
가 커밋을 제거하기 위해 업스트림의 기록을 다시 작성하므로 다음에 git rebase
를 실행할 때 다른 커밋처럼 삭제합니다. 업스트림에서 제거되었습니다.
그러나 이 특별한 경우에 우리는 그 3개의 커밋이 토픽 브랜치의 일부로 고려되기를 원합니다. 이를 달성하려면 3개의 커밋을 포함하지 않는 이전 개정판에서 업스트림을 분기해야 합니다. 이것이 내가 제안한 솔루션이 수행하는 작업이므로 둘 다 reflog를 올바른 상태로 둡니다.
자세한 내용은 git rebase 및 git merge-base 문서 --fork-point
정의를 참조하세요.
답변자 : aragaer
이 작업을 수행하는 또 다른 방법은 단 2개의 명령을 사용하는 것입니다. 또한 현재 작업 트리를 그대로 유지합니다.
git checkout -b newbranch # switch to a new branch git branch -f master HEAD~3 # make master point to some older commit
이전 버전 git branch -f
대해 배우기 전
git checkout -b newbranch # switch to a new branch git push . +HEAD~3:master # make master point to some older commit
로 push
할 수 .
알아두면 좋은 트릭입니다.
답변자 : Slam
다음은 잘못된 분기에 대한 커밋에 대한 훨씬 간단한 솔루션입니다. 세 번의 잘못된 커밋이 있는 master
에서 시작:
git reset HEAD~3 git stash git checkout newbranch git stash pop
master
master
대한 마지막 세 커밋(및 해당 메시지)을 취소하지만 모든 작업 파일은 그대로 둡니다.master
작업 트리를 HEAD~3 상태와 정확히 동일하게 만듭니다.newbranch
이제 평소처럼 git add
및 git commit
을 사용할 수 있습니다. 모든 새 커밋은 newbranch
추가됩니다.
OP는 목표가 변경 사항을 잃지 않고 "해당 커밋이 수행되기 전으로 마스터를 되돌리는 것"이라고 밝혔으며 이 솔루션이 이를 수행합니다.
develop
대신 master
새로운 커밋을 만들 때 적어도 일주일에 한 번 이 작업을 수행합니다. 일반적으로 롤백할 커밋은 하나만 있는데 git reset HEAD^
를 사용하는 것이 커밋 하나만 롤백하는 더 간단한 방법입니다.
마스터의 변경 사항을 업스트림으로 푸시한 경우에는 이 작업을 수행하지 마십시오.
다른 사람이 이러한 변경 사항을 가져왔을 수 있습니다. 로컬 마스터만 다시 작성하는 경우 업스트림으로 푸시할 때 영향이 없지만 다시 작성된 기록을 공동 작업자에게 푸시하면 골치 아픈 문제가 발생할 수 있습니다.
답변자 : Sukima
이것은 기술적 의미에서 "이동"하지 않지만 동일한 효과가 있습니다.
A--B--C (branch-foo) \ ^-- I wanted them here! \ D--E--F--G (branch-bar) ^--^--^-- Opps wrong branch! While on branch-bar: $ git reset --hard D # remember the SHAs for E, F, G (or E and G for a range) A--B--C (branch-foo) \ \ D-(E--F--G) detached ^-- (branch-bar) Switch to branch-foo $ git cherry-pick E..G A--B--C--E'--F'--G' (branch-foo) \ E--F--G detached (This can be ignored) \ / D--H--I (branch-bar) Now you won't need to worry about the detached branch because it is basically like they are in the trash can waiting for the day it gets garbage collected. Eventually some time in the far future it will look like: A--B--C--E'--F'--G'--L--M--N--... (branch-foo) \ \ D--H--I--J--K--.... (branch-bar)
답변자 : teh_senaus
기록을 다시 작성하지 않고 이를 수행하려면(즉, 이미 커밋을 푸시한 경우):
git checkout master git revert <commitID(s)> git checkout -b new-branch git cherry-pick <commitID(s)>
그러면 두 가지 모두 힘 없이 밀 수 있습니다!
답변자 : Saikat
1. 이름 바꾸기 master
당신에 지점 newbranch
(당신은에있는 가정 master
지점)
git branch -m newbranch
2. 원하는 커밋에서 master
브랜치를 생성합니다.
git checkout -b master <seven_char_commit_id>
예: git checkout -b master a34bc22
답변자 : Darkglow
이 상황이 있었다:
Branch one: ABCDEFJLM \ (Merge) Branch two: GIKN
나는 수행 :
git branch newbranch git reset --hard HEAD~8 git checkout newbranch
커밋이 내가 HEAD가 될 것이라고 예상했지만 커밋 L이 지금입니다 ...
기록의 올바른 위치에 착륙하려면 커밋의 해시로 작업하는 것이 더 쉽습니다.
git branch newbranch git reset --hard ######### git checkout newbranch
답변자 : Ivan
이거에서 어떻게 갈 수 있어?
A - B - C - D - E | master
이에?
A - B - C - D - E | | master newbranch
두 가지 명령으로
기부
A - B - C - D - E | newbranch
그리고
기부
A - B - C - D - E | | master newbranch
답변자 : Shamsul Arefin Sajib
푸시되지 않은 모든 커밋을 새 분기 로 이동해야 하는 경우 다음을 수행하면 됩니다.
현재 브랜치에서 새 브랜치 생성 git branch new-branch-name
새 분기를 밀어 : git push origin new-branch-name
지난 밀어 / 안정된 상태로 이전 (현재) 브랜치를 되돌릴 : git reset --hard origin/old-branch-name
어떤 사람들은 origin
upstreams
가지고 있기 때문에 upstream
을 사용해야 합니다.
답변자 : pankaj
내가 사용한 간단한 3단계만 수행하면 됩니다.
1) 최근 업데이트를 커밋하려는 새 분기를 만듭니다.
git branch <branch name>
2) 새 브랜치에 대한 커밋에 대한 최근 커밋 ID를 찾습니다.
git log
3) 가장 최근의 커밋 목록이 맨 위에 있다는 커밋 ID를 복사합니다. 커밋을 찾을 수 있습니다. 당신은 또한 메시지를 통해 이것을 찾을 수 있습니다.
git cherry-pick d34bcef232f6c...
커밋 ID 범위를 제공할 수도 있습니다.
git cherry-pick d34bcef...86d2aec
이제 작업이 완료되었습니다. 올바른 ID와 올바른 분기를 선택했다면 성공할 것입니다. 그래서 이것을하기 전에 조심하십시오. 그렇지 않으면 다른 문제가 발생할 수 있습니다.
이제 코드를 푸시할 수 있습니다.
git push
답변자 : rashok
1) 모든 변경 사항을 new_branch로 이동하는 새 분기를 만듭니다.
git checkout -b new_branch
2) 그런 다음 이전 분기로 돌아갑니다.
git checkout master
3) git rebase 실행
git rebase -i <short-hash-of-B-commit>
4) 그런 다음 열린 편집기에는 마지막 3개의 커밋 정보가 포함됩니다.
... pick <C's hash> C pick <D's hash> D pick <E's hash> E ...
5) 3개의 모든 커밋에서 pick
을 drop
그런 다음 편집기를 저장하고 닫습니다.
... drop <C's hash> C drop <D's hash> D drop <E's hash> E ...
6) 이제 마지막 3개의 커밋이 현재 분기( master
)에서 제거됩니다. 이제 브랜치 이름 앞에 +
기호를 사용하여 브랜치를 강제로 푸시합니다.
git push origin +master
답변자 : Quesofat
여기에 있는 대부분의 솔루션은 되돌리려는 커밋의 양을 계산합니다. 나는 이것이 오류가 발생하기 쉬운 방법론이라고 생각한다. 계산에는 다시 계산이 필요합니다.
HEAD에 있고 싶은 커밋의 커밋 해시를 전달하거나 다음을 통해 마지막 커밋이 되고 싶은 커밋을 전달할 수 있습니다.
(커밋 해시 참조)
이것을 피하려면:
1) git checkout master 2) git branch <feature branch> master 3) git reset --hard <commit hash> 4) git push -f origin master
출처 : Here
출처 : http:www.stackoverflow.com/questions/1628563/move-the-most-recent-commits-to-a-new-branch-with-git">
"yield" 키워드는 무엇을 합니까? (0) | 2021.09.23 |
---|---|
두 개의 사전을 단일 표현식으로 병합하려면(사전 통합 사용) 어떻게 하나요? (0) | 2021.09.23 |
Python에 삼항 조건 연산자가 있습니까? (0) | 2021.09.23 |
'git pull'과 'git fetch'의 차이점은 무엇입니까? (0) | 2021.09.23 |
다른 웹페이지로 리디렉션하려면 어떻게 합니까? (0) | 2021.09.23 |