마지막 X 커밋을 Git을 사용하여 하나의 커밋으로 어떻게 스쿼시 할 수 있습니까?
마지막 X 커밋을 Git을 사용하여 하나의 커밋으로 어떻게 스쿼시 할 수 있습니까?
답변:
매뉴얼에git rebase -i <after-this-commit>
설명 된대로 두 번째 및 후속 커밋에서 "pick"을 사용 하고 "squash"또는 "fixup"으로 바꿉니다 .
이 예에서, <after-this-commit>
rebase 명령에 대한 커밋이 분석되는 현재 분기의 HEAD로부터의 SHA1 해시 또는 상대 위치입니다. 예를 들어, 사용자가 과거에 현재 HEAD에서 5 개의 커밋을 보려면 명령은 git rebase -i HEAD~5
입니다.
<after-this-commit>
합니까?
<after-this-commit>
커밋 X + 1, 즉 스쿼시하려는 가장 오래된 커밋의 부모입니다.
rebase -i
접근하고 reset --soft
,되는 rebase -i
동안, 나를이 저자를 저지 유지할 수 있습니다 reset --soft
나를 재회 할 수 있습니다. 때로는 저자 정보를 유지하면서 풀 요청 커밋을 스쿼시해야합니다. 때로는 내 커밋에서 소프트를 재설정해야합니다. 어쨌든 두 가지 큰 답변 모두에 찬성합니다.
git rebase
또는 없이이 작업을 상당히 쉽게 수행 할 수 있습니다 git merge --squash
. 이 예에서는 마지막 3 개의 커밋을 스쿼시합니다.
새로운 커밋 메시지를 처음부터 작성하려면 다음과 같이 충분합니다.
git reset --soft HEAD~3 &&
git commit
기존 커밋 메시지를 연결하여 새 커밋 메시지 편집을 시작하려면 (예 : pick / squash / squash /… / squash git rebase -i
명령어 목록 과 유사 ) 해당 메시지를 추출하여 전달해야합니다. 그들에게 git commit
:
git reset --soft HEAD~3 &&
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
이 두 가지 방법 모두 마지막 3 개의 커밋을 같은 방식으로 하나의 새로운 커밋으로 뭉칩니다. 소프트 리셋은 스쿼시하지 않으려는 마지막 커밋으로 HEAD를 다시 가리 킵니다. 소프트 재설정으로 인덱스와 작업 트리를 건드리지 않고 새 커밋에 대해 원하는 상태로 인덱스를 유지합니다 (즉, 이미 "버려 버리려는 커밋의 모든 변경 사항이 이미 있습니다").
git rebase --squash-recent
, 또는 심지어 git commit --amend-many
.
branch@{upstream}
(또는 @{upstream}
현재의 지점에 대해, 두 경우 모두, 마지막 부분에 생략 할 수있다 @{u}
; 참조 gitrevisions을 ). 이 다를 수 있습니다 귀하의 "커밋 밀어 마지막으로"(예를 들어 다른 사람이 가장 최근의 푸시 꼭대기에 건설 한 다음 그것을 가져온 것을 무언가를 밀어 경우),하지만 가까이 당신이 원하는에있을 것 같다.
push -f
했지만 그렇지 않으면 사랑 스럽습니다. 감사합니다.
git push --force
커밋을 수행 할 수 있도록 나중에 사용해야 합니다.
git merge --squash
이보다 약간 더 우아하게 사용할 수 있습니다 git rebase -i
. 당신이 마스터에 있고 마지막 12 개의 커밋을 하나로 묶고 싶다고 가정 해보십시오.
경고 : 먼저 작업을 커밋해야합니다. 단계적이거나 단계적이지 않은 변경 사항을 버릴 git status
것이므로 깨끗한 지 확인하십시오.git reset --hard
그때:
# Reset the current branch to the commit just before the last 12:
git reset --hard HEAD~12
# HEAD@{1} is where the branch was just before the previous command.
# This command sets the state of the index to be as it would just
# after a merge from that commit:
git merge --squash HEAD@{1}
# Commit those squashed changes. The commit message will be helpfully
# prepopulated with the commit messages of all the squashed commits:
git commit
에 대한 문서는git merge
설명 --squash
자세히 옵션을 선택합니다.
업데이트 :git reset --soft HEAD~12 && git commit
Chris Johnsen이 그의 대답 에서 제안한 것보다 더 간단한이 방법의 유일한 장점 은 스쿼시하는 모든 커밋 메시지로 커밋 메시지가 미리 채워져 있다는 것입니다.
git rebase -i
이유를 제시하지는 않습니다. 실제로 반대의 경우가 사실이며 이것이 해킹 인 것 같습니다. 특별히 설계된 git merge
것 중 하나를 수행 하기 위해 필요한 것보다 많은 명령을 수행하지 git rebase
않습니까?
git merge --squash
스크립트에서도 사용하기 가 더 쉽습니다. 본질적으로, 추론은 당신이 전혀 "상호 작용"을 필요로하지 않기 때문 git rebase -i
입니다.
git merge --squash
특히 로컬 지점에서 병합하는 경우 rebasing에 비해 이동 / 삭제 / 이름 변경시 병합 충돌이 발생할 가능성이 적다는 것입니다. (면책 조항 : 하나의 경험 만 바탕으로, 일반적인 경우에 해당되지 않는 경우 수정하십시오!)
HEAD@{1}
예를 들어 워크 플로가 정전 등으로 1 시간 동안 중단 된 경우와 같이 안전한면이 아닌 임시 태그를 사용합니다 .
git reset
가능하면 특히 Git-novices를 피하는 것이 좋습니다 . 많은 커밋을 기반으로 프로세스를 자동화 해야하는 경우가 아니라면 덜 이국적인 방법이 있습니다 ...
git merge --squash (working branch name)
git commit
커밋 메시지는 스쿼시를 기반으로 미리 채워집니다.
gitk
스쿼시중인 코드 줄에 레이블을 지정하고 스쿼시 할 기준에 레이블을 지정합니다. 일반적인 경우 두 레이블이 모두 존재하므로 단계 (1)을 건너 뛸 수 있습니다.
git branch your-feature && git reset --hard HEAD~N
경우 가장 편리한 방법을 찾았 습니다. 그러나 git reset을 다시 포함 하므로이 답변은 피하려고했습니다.
을 바탕으로 크리스 욘센의 대답은 ,
bash에서 전역 "스쿼시"별칭 추가 : (또는 Windows의 Git Bash)
git config --global alias.squash '!f(){ git reset --soft HEAD~${1} && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"; };f'
... 또는 Windows 명령 프롬프트 사용 :
git config --global alias.squash "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"
당신은 ~/.gitconfig
지금이 별칭을 포함해야한다 :
[alias]
squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"
용법:
git squash N
... 마지막 N
커밋을 자동으로 묶습니다 .
참고 : 결과 커밋 메시지는 모든 스와치 된 커밋을 순서대로 조합 한 것입니다. 마음에 들지 않으면 언제든지 git commit --amend
수동으로 수정할 수 있습니다. 또는 취향에 맞게 별칭을 편집하십시오.
git squash -m "New summary."
하고 N
결정했습니다.
git commit --amend
하면 메시지를 추가로 변경할 수 있지만이 별칭을 사용하면 커밋 메시지에 포함되어야 할 내용을 잘 시작할 수 있습니다.
이 편리한 블로그 게시물 덕분 에이 명령을 사용하여 마지막 3 개의 커밋을 스쿼시 할 수 있음을 발견했습니다.
git rebase -i HEAD~3
추적 정보 / 원격 리포지토리가없는 로컬 지점에 있어도 편리합니다.
이 명령은 대화식 rebase 편집기를 열고 평소대로 재정렬, 스쿼시, 리워드 등을 수행 할 수 있습니다.
대화식 rebase 편집기 사용 :
대화식 rebase 편집기는 마지막 3 개의 커밋을 보여줍니다. 이 제한 조건은 HEAD~3
명령을 실행할 때 결정됩니다 git rebase -i HEAD~3
.
가장 최근의 커밋 HEAD
이 첫 번째 줄에 먼저 표시됩니다.로 시작하는 줄 #
은 주석 / 문서입니다.
표시되는 문서는 매우 명확합니다. 주어진 행 pick
에서 명령을 원하는 명령으로 변경할 수 있습니다 .
fixup
이 명령 은 커밋 변경 사항을 위의 줄에 커밋으로 "제곱"하고 커밋 메시지를 삭제 하기 때문에 명령을 사용하는 것을 선호 합니다.
1 행의 커밋 HEAD
이 대부분이므로 대부분의 경우이를 그대로 둡니다 pick
. 당신은 사용할 수 없습니다 squash
또는 fixup
이 있기 때문에 다른이 (가)에 커밋 스쿼시 것을 약속합니다.
커밋 순서를 변경할 수도 있습니다. 이를 통해 연대순으로 인접하지 않은 커밋을 스쿼시하거나 수정할 수 있습니다.
실용적인 일상 예
최근에 새로운 기능을 커밋했습니다. 그 이후로 두 가지 버그 수정을했습니다. 그러나 이제는 내가 저지른 새로운 기능에서 버그 (또는 철자 오류)를 발견했습니다. 짜증나! 커밋 기록을 오염시키는 새로운 커밋을 원하지 않습니다!
내가하는 첫 번째 일은 실수를 고치고 코멘트로 새로운 커밋을하는 것 squash this into my new feature!
입니다.
그런 다음 새로운 기능 (이 경우 ) 의 커밋 SHA 를 실행 git log
하거나 gitk
얻습니다 1ff9460
.
다음으로를 사용하여 대화식 rebase 편집기를 불러옵니다 git rebase -i 1ff9460~
. ~
커밋 후 SHA 편집기에서 커밋이 포함 편집기를 알려줍니다.
다음으로 수정 ( fe7f1e0
)이 포함 된 커밋을 기능 커밋 아래 로 이동 하고로 변경 pick
합니다 fixup
.
편집기를 닫을 때 수정 사항이 기능 커밋으로 찌그러지고 커밋 기록이 멋지고 깨끗하게 보입니다!
이것은 모든 커밋이 로컬 인 경우 잘 작동하지만 이미 원격으로 푸시 된 커밋을 변경하려고하면 동일한 분기를 체크 아웃 한 다른 개발자에게 실제로 문제가 발생할 수 있습니다!
pick
1 행 에 그대로 두십시오 . squash
또는 fixup
1 행에서 커밋을 선택하면 git은 "오류 : 이전 커밋없이 '수정'할 수 없습니다"라는 메시지를 표시합니다. 그런 다음 수정 옵션을 제공합니다. " 'git rebase --edit-todo'로이 문제를 해결 한 다음 'git rebase --continue'를 실행할 수 있습니다." 또는 중단하거나 다시 시작할 수 있습니다. "또는 'git rebase --abort'로 리베이스를 중단 할 수 있습니다."
TortoiseGit을 사용하면 다음과 같은 기능을 수행 할 수 있습니다 Combine to one commit
.
Show Log
Combine to one commit
상황에 맞는 메뉴에서 선택이 기능은 필요한 모든 단일 git 단계를 자동으로 실행합니다. 불행히도 Windows에서만 사용할 수 있습니다.
이를 위해 다음 git 명령을 사용할 수 있습니다.
git rebase -i HEAD~n
n (= 4 here)은 마지막 커밋 수입니다. 그런 다음 다음 옵션을 얻습니다.
pick 01d1124 Message....
pick 6340aaa Message....
pick ebfd367 Message....
pick 30e0ccb Message....
아래와 같이 업데이트 pick
한 커밋 squash
가장 최근에 다른 사람,
p 01d1124 Message....
s 6340aaa Message....
s ebfd367 Message....
s 30e0ccb Message....
자세한 내용은 링크를 클릭하십시오
이 기사를 바탕 으로이 방법이 사용 사례에서 더 쉽다는 것을 알았습니다.
내 'dev'브랜치는 96 커밋으로 'origin / dev'보다 앞서있었습니다 (따라서 커밋은 아직 원격으로 푸시되지 않았습니다).
변경 사항을 적용하기 전에 이러한 커밋을 하나로 스쿼시하고 싶었습니다. 분기를 'origin / dev'상태로 재설정하고 (96 커밋의 모든 변경 사항을 비 스테이지로 남겨 둡니다) 변경 사항을 한 번에 커밋합니다.
git reset origin/dev
git add --all
git commit -m 'my commit message'
지점에서 커밋을 결합하려면 다음을 실행하십시오.
git rebase -i HEAD~(n number of commits back to review)
예:
git rebase -i HEAD~1
그러면 텍스트 편집기가 열리고 커밋을 함께 병합하려면 각 커밋 앞에서 'pick'을 'squash'로 전환해야합니다. 설명서에서 :
예를 들어, 모든 커밋을 하나로 병합하려는 경우 'pick'은 첫 번째 커밋이며 이후의 모든 커밋 (첫 번째 아래에 배치)은 'squash'로 설정해야합니다. vim을 사용하는 경우 삽입 모드에서 : x 를 사용 하여 편집기를 저장하고 종료하십시오.
그런 다음 리베이스를 계속하십시오.
git rebase --continue
커밋 기록을 다시 작성하는 방법과 다른 방법에 대한 자세한 내용은 이 유용한 게시물을 참조하십시오.
--continue
그리고 vim :x
이 무엇을하는지 설명하십시오 .
Anomies의 대답 은 좋지만, 이것에 대해 불안감을 느꼈기 때문에 몇 개의 스크린 샷을 추가하기로 결정했습니다.
현재 위치를 확인하십시오 git log
. 가장 중요한 것은 스쿼시 하지 않으려 는 첫 번째 커밋의 커밋 해시를 찾으십시오 . 따라서 :
git rebase -i [your hash]
내 경우에는을 실행하십시오 .
$ git rebase -i 2d23ea524936e612fae1ac63c95b705db44d937d
필자의 경우, 처음 커밋에서 모든 것을 스쿼시하고 싶습니다. 순서는 처음부터 끝까지입니다 git log
. 제 경우에는 다음을 원합니다.
커밋을 하나만 선택하고 나머지는 스쿼시 한 경우 하나의 커밋 메시지를 조정할 수 있습니다.
그게 다야. 이 ( :wq
) 를 저장하면 완료됩니다. 로 살펴보십시오 git log
.
git log
1) 커밋 쇼트 해시 식별
# git log --pretty=oneline --abbrev-commit
abcd1234 Update to Fix for issue B
cdababcd Fix issue B
deab3412 Fix issue A
....
여기에서도 git log --oneline
짧은 해시를 얻는 데 사용할 수 있습니다.
2) 마지막 두 커밋을 스쿼시 (병합)하려는 경우
# git rebase -i deab3412
3) nano
병합을 위한 편집기 가 열립니다 . 그리고 그것은 아래와 같습니다
....
pick cdababcd Fix issue B
pick abcd1234 Update to Fix for issue B
....
4) 단어 바꾸기 pick
에 squash
앞서 존재하는이 abcd1234
. 이름을 바꾼 후에는 다음과 같아야합니다.
....
pick cdababcd Fix issue B
squash abcd1234 Update to Fix for issue B
....
5) 이제 nano
편집기를 저장하고 닫습니다 . 보도 ctrl + o
하고 Enter 키를 눌러 Enter
저장합니다. 그런 다음을 눌러 ctrl + x
편집기를 종료하십시오.
6) nano
필요한 경우 편집기를 다시 열어 주석을 업데이트합니다 (필요한 경우).
7) 이제 성공적으로 뭉개졌습니다. 로그를 확인하여 확인할 수 있습니다.
# git log --pretty=oneline --abbrev-commit
1122abcd Fix issue B
deab3412 Fix issue A
....
8) 이제 repo로 밉니다. +
지점 이름 앞에 부호 를 추가 하십시오. 이것은 강제 푸시를 의미합니다.
# git push origin +master
참고 : 이것은 git on ubuntu
shell을 기반으로 합니다. 다른 os ( Windows
또는 Mac
)를 사용하는 경우 위의 명령은 편집기를 제외하고 동일합니다. 다른 편집기를 얻을 수 있습니다.
git add <files>
--fixup
옵션을 사용하여 커밋 OLDCOMMIT
하고이 커밋을 병합 (스쿼시)해야합니다.git commit --fixup=OLDCOMMIT
이제와 함께 HEAD 위에 새로운 커밋을 만듭니다 fixup1 <OLDCOMMIT_MSG>
.
OLDCOMMIT
.git rebase --interactive --autosquash OLDCOMMIT^
에 ^
대한 이전 커밋을 의미합니다 OLDCOMMIT
. 이 rebase
명령은 편집기 (vim 또는 nano)에서 대화식 창을 열어 저장하고 종료하기 만하면됩니다. 이 옵션이 전달되면 최신 커밋이 이전 커밋 옆으로 자동 이동되고 작업이 fixup
(스쿼시와 동일)로 변경됩니다. 그런 다음 리베이스가 계속되고 완료됩니다.
--amend
와 함께 사용할 수 있습니다 git-commit
. # git log --pretty=oneline --abbrev-commit
cdababcd Fix issue B
deab3412 Fix issue A
....
# git add <files> # New changes
# git commit --amend
# git log --pretty=oneline --abbrev-commit
1d4ab2e1 Fix issue B
deab3412 Fix issue A
....
여기에 --amend
커밋 마지막에 새로운 변화를 병합 cdababcd
하고 새로운 ID를 저지 생성1d4ab2e1
feature-branch
Golden Repository ( golden_repo_name
) 에서 복제 된 원격 분기 ( ) 에있는 경우 커밋을 하나로 스쿼시하는 기술은 다음과 같습니다.
골든 레포 확인
git checkout golden_repo_name
다음과 같이 새 지점 (골든 리포지토리)을 만듭니다.
git checkout -b dev-branch
스쿼시는 이미 가지고있는 지역 지점과 합병
git merge --squash feature-branch
변경 사항을 커밋하십시오 (dev-branch로 진행되는 유일한 커밋입니다)
git commit -m "My feature complete"
지점을 로컬 리포지토리로 푸시
git push origin dev-branch
정말 편리한 것 :
스쿼시하려는 커밋 해시를 찾으십시오 d43e15
.
이제 사용
git reset d43e15
git commit -am 'new commit name'
이것은 슈퍼 듀퍼 클루 지이지만 멋진 방법으로 링에 던져 넣을 것입니다.
GIT_EDITOR='f() { if [ "$(basename $1)" = "git-rebase-todo" ]; then sed -i "2,\$s/pick/squash/" $1; else vim $1; fi }; f' git rebase -i foo~5 foo
번역 : 편집 할 파일 이름이 git-rebase-todo
(대화 형 rebase prompt) 경우 첫 번째 "pick"을 제외한 모든 것을 "squash"로 변경하고 그렇지 않으면 vim을 생성 하는 git에 대한 새로운 "편집기"를 제공 하십시오. 숙청 된 커밋 메시지를 편집하려면 vim을 얻는다. (그리고 분명히 나는 foo 브랜치에서 마지막 5 개의 커밋을 스쿼시하고 있었지만 원하는대로 변경할 수 있습니다.)
그래도 Mark Longair가 제안한 것을 할 것입니다 .
가장 쉬운 방법은 마스터에서 새 브랜치를 만들고 기능 브랜치를 병합하는 것입니다.
git checkout master
git checkout -b feature_branch_squashed
git merge --squash feature_branch
그런 다음 모든 변경 사항을 커밋 할 준비가되었습니다.
현재 스쿼시하려는 브랜치에 있고 마스터는 브랜치에서 시작한 브랜치이며 최신 커밋에는 커밋 메시지와 사용하려는 작성자가 포함되어 있으므로 항상 작동하는 간단한 단일 라이너.
git reset --soft $(git merge-base HEAD master) && git commit --reuse-message=HEAD@{1}
예를 들어 https://bitbucket.org 와 같이 지점 (원격 저장소)의 단일 커밋에 대한 마지막 3 개의 커밋을 스쿼시하려는 경우
내가 한 일은
(MASTER)
Fleetwood Mac Fritz
║ ║
Add Danny Lindsey Stevie
Kirwan Buckingham Nicks
║ ╚═══╦══════╝
Add Christine ║
Perfect Buckingham
║ Nicks
LA1974══════════╝
║
║
Bill <══════ YOU ARE EDITING HERE
Clinton (CHECKED OUT, CURRENT WORKING DIRECTORY)
https://github.com/fleetwood-mac/band-history 리포지토리 의 매우 약식 기록 에서 Bill Clinton 커밋을 원래의 MASTER
Fleetwood Mac 커밋 으로 병합하기위한 풀 요청을 열었습니다 .
풀 요청을 열었고 GitHub에서 다음을 볼 수 있습니다.
네 가지 커밋 :
아무도 전체 저장소 기록을 읽을 필요가 없다고 생각합니다. (실제로 저장소가 있으므로 위의 링크를 클릭하십시오!) 이러한 커밋을 스쿼시하기로 결정했습니다. 그래서 당신은 가서 실행 git reset --soft HEAD~4 && git commit
합니다. 그런 다음 git push --force
GitHub에서 PR을 정리하십시오.
그리고 어떻게됩니까? 프리츠에서 빌 클린턴까지 한 번 커밋했습니다. 어제 잊어 버렸기 때문에이 프로젝트의 Buckingham Nicks 버전을 작업하고있었습니다. 그리고 git log
GitHub에 표시되는 것과 일치하지 않습니다.
git checkout
그들git reset --soft
그git commit
로부터 직접 그 뒤틀림을 에서 받는 사람 에다른 훌륭한 답변 외에도 git rebase -i
커밋 순서와 항상 혼동되는 방법을 추가하고 싶습니다 . 이것이 내 워크 플로입니다.
git rebase -i HEAD~[N]
여기서 N은 가장 최근에 시작한 커밋 수입니다 . 그래서 git rebase -i HEAD~5
"새로 지난 5 커밋 스쿼시"의미;이와 같은 워크 플로와 관련된 질문에 대한 답변은 어떻습니까?
merge --squash
PR 을 따르는 것이 더 쉬울 것이지만 팀은 프로세스 속도가 느려질 것이라고 생각했습니다.)이 페이지에서 이와 같은 워크 플로를 보지 못했습니다. (내 눈이 될 수도 있습니다.) rebase
올바르게 이해 하면 여러 번 병합하면 여러 가지 충돌 해결 이 필요합니다 . 나는 그것에 대해 생각조차하고 싶지 않습니다!
그래서 이것은 우리에게 효과가있는 것 같습니다.
git pull master
git checkout -b new-branch
git checkout -b new-branch-temp
git checkout new-branch
git merge --squash new-branch-temp
// 모든 변경 사항을 스테이지에 넣습니다.git commit 'one message to rule them all'
git push
더 일반적인 해결책은 'N'커밋을 지정하는 것이 아니라 스쿼시하려는 분기 / 커밋 ID를 찾는 것입니다. 특정 커밋까지 커밋을 계산하는 것보다 오류가 덜 발생합니다. 태그를 직접 지정하거나 실제로 계산하려면 HEAD ~ N을 지정할 수 있습니다.
워크 플로에서 지점을 시작하면 해당 지점에 대한 첫 번째 커밋이 목표를 요약합니다 (즉, 일반적으로 해당 기능에 대한 '최종'메시지로 공용 리포지토리에 푸시하는 것입니다). I는하고 싶은 git squash master
첫 번째 메시지 다시 다음 내가 밀어 준비 해요.
별명을 사용합니다.
squash = !EDITOR="\"_() { sed -n 's/^pick //p' \"\\$1\"; sed -i .tmp '2,\\$s/^pick/f/' \"\\$1\"; }; _\"" git rebase -i
이렇게하면 이전에 찌그러진 기록이 덤프됩니다. 되돌릴 경우 콘솔에서 오래된 커밋 ID를 가져와 복구 할 수 있습니다. (Solaris 사용자는 GNU sed -i
옵션을 사용하므로 Mac 및 Linux 사용자는 이에 적합해야합니다.)
git squash master
하고 슬레이브에서 체크 아웃 할 때 사용 합니다. 어떻게됩니까? 우리는 갈등을 숨길 것인가?
문제는 "마지막"의 의미가 모호 할 수 있습니다.
예를 들어 git log --graph
다음과 같이 출력됩니다 (단순화).
* commit H0
|
* merge
|\
| * commit B0
| |
| * commit B1
| |
* | commit H1
| |
* | commit H2
|/
|
그런 다음 시간별 마지막 커밋은 H0, merge, B0입니다. 스쿼시하려면 커밋 H1에 병합 된 브랜치를 리베이스해야합니다.
문제는 H0에 H1과 H2가 포함되어 있으며 (B는 병합하지 않고 분기 후 더 많은 커밋) B0에는 없습니다. 따라서 최소한 H0, merge, H1, H2, B0의 변경 사항을 관리해야합니다.
rebase를 사용할 수는 있지만 다른 방법으로 대답 할 수 있습니다.
rebase -i HEAD~2
그러면 다른 답변에서 언급 한대로 선택 옵션이 표시됩니다.
pick B1
pick B0
pick H0
H0 대신 pick 대신 squash를 넣습니다.
pick B1
pick B0
s H0
저장 후 종료 후 rebase는 H1 이후에 커밋을 차례로 적용합니다. 즉, 충돌을 다시 해결하도록 요청합니다 (처음에는 HEAD가 H1이되고 적용되는 커밋이 누적 됨).
리베이스가 완료되면 찌그러진 H0 및 B0에 대한 메시지를 선택할 수 있습니다.
* commit squashed H0 and B0
|
* commit B1
|
* commit H1
|
* commit H2
|
그냥 BO 일부 리셋을 할 경우 PS : (예를 들어, 사용 reset --mixed
이 여기에 자세히 설명되어 https://stackoverflow.com/a/18690845/2405850 ) :
git reset --mixed hash_of_commit_B0
git add .
git commit -m 'some commit message'
그런 다음 H0, H1, H2의 B0 변경으로 스쿼시합니다. 분기 후 및 병합 전에 변경 사항을 완전히 커밋하지 않습니다.