programing

Git 저장소에서 선택한 커밋 로그 항목을 변경 사항을 유지하면서 제거하는 방법은 무엇입니까?

itmemos 2023. 7. 11. 21:36
반응형

Git 저장소에서 선택한 커밋 로그 항목을 변경 사항을 유지하면서 제거하는 방법은 무엇입니까?

선택한 커밋 로그 항목을 선형 커밋 트리에서 제거하여 항목이 커밋 로그에 표시되지 않도록 합니다.

내 커밋 트리는 다음과 같습니다.

R--A--B--C--D--E--HEAD

B와 C 항목은 커밋 로그에 표시되지 않도록 제거하고 싶지만, A에서 D로의 변경 사항은 유지해야 합니다.아마도 단일 커밋을 도입함으로써 B와 C가 BC가 되고 트리는 다음과 같이 보입니다.

R--A--BC--D--E--HEAD

또는, 이상적으로는, A 다음에 D가 직접 옵니다.D'는 A에서 B로, B에서 C로, C에서 D로 변화를 나타냅니다.

R--A--D'--E--HEAD

이것이 가능합니까?만약 그렇다면, 어떻게?

이것은 상당히 새로운 프로젝트이기 때문에 현재 지점이 없기 때문에 합병도 없습니다.

git-rebase(1)는 정확히 그렇게 합니다.

$ git rebase -i HEAD~5

git awome-ness [git rebase --propertive]에는 예제가 포함되어 있습니다.

  1. 사용 안 함git-rebase공개(원격) 커밋 시
  2. 작업 디렉토리가 깨끗한지 확인합니다(commit또는stash현재 변경 사항).
  3. 위의 명령을 실행합니다.시작합니다.$EDITOR.
  4. 교체하다pick전에C그리고.D타고squash그것은 C와 D를 B로 녹일 것입니다.커밋을 삭제하려면 해당 줄을 삭제하십시오.

길을 잃은 경우 다음을 입력합니다.

$ git rebase --abort  
# detach head and move to D commit
git checkout <SHA1-for-D>

# move HEAD to A, but leave the index and working tree as for D
git reset --soft <SHA1-for-A>

# Redo the D commit re-using the commit message, but now on top of A
git commit -C <SHA1-for-D>

# Re-apply everything from the old D onwards onto this new place 
git rebase --onto HEAD <SHA1-for-D> master

다음은 제거할 커밋 ID만 알고 있는 특정 커밋 ID를 제거하는 방법입니다.

git rebase --onto commit-id^ commit-id

이렇게 하면 실제로 커밋에 의해 도입된 변경 사항이 제거됩니다.

J.F.로 확장합니다.세바스찬의 대답:

git-rebase를 사용하여 커밋 기록을 쉽게 변경할 수 있습니다.

gitrebase --interactive를 실행하면 $EDIOR에서 다음과 같은 정보를 얻을 수 있습니다.

pick 366eca1 This has a huge file
pick d975b30 delete foo
pick 121802a delete bar
# Rebase 57d0b28..121802a onto 57d0b28
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit

줄을 이동하여 커밋 순서를 변경하고 줄을 삭제하여 해당 커밋을 제거할 수 있습니다.또는 두 개의 커밋을 단일 커밋으로 결합(소멸)하는 명령을 추가하거나(이전 커밋이 위 커밋임) 커밋을 편집하거나(변경된 내용) 커밋 메시지를 다시 정의할 수 있습니다.

제 생각에 선택은 단지 당신이 그 약속을 그냥 내버려두고 싶다는 것을 의미하는 것입니다.

(예는 여기에서)

다음을 사용하여 예제에서 B 및 C를 비대화형으로 제거할 수 있습니다.

git rebase --onto HEAD~5 HEAD~3 HEAD

아니면 상징적으로

git rebase --onto A C HEAD

B와 C의 변경 사항은 D가 아니라 사라집니다.

저는 A의 SHA1에서 다른 브랜치를 생성하고 원하는 변경 사항을 선택하여 이 새로운 브랜치가 어떻게 보이는지에 대해 만족할 수 있도록 함으로써 이 프로세스를 훨씬 더 안전하고 이해하기 쉽다는 것을 알게 되었습니다.그런 다음 이전 분기를 제거하고 새 분기의 이름을 쉽게 변경할 수 있습니다.

git checkout <SHA1 of A>
git log #verify looks good
git checkout -b rework
git cherry-pick <SHA1 of D>
....
git log #verify looks good
git branch -D <oldbranch>
git branch -m rework <oldbranch>

한 가지 더,

git rebase -i ad0389efc1a79b1f9c4dd6061dca6edc1d5bb78a (C's hash)
and
git push origin master  -f

기본으로 사용할 해시를 선택하고, 위의 명령은 모든 상위 메시지를 스퀴시할 수 있도록 대화형으로 만들어야 합니다(가장 오래된 메시지를 남겨야 함).

방금 모든 사람들의 답변을 수집했습니다. (git에 새로 온 사람입니다. 참조용으로만 사용하십시오.)

모든 커밋을 삭제하기 위한 gitrebase

깃 로그

-first check from which commit you want to rebase

gitrebase -i HEAD~1

-Here i want to rebase on the second last commit- commit count starts from '1')
-this will open the command line editor (called vim editor i guess)

그러면 화면이 다음과 같이 표시됩니다.

pick 0c2236d 새 줄 추가.

기본값 2a1cd65..0c2236d에서 2a1cd65(1 명령)로 이동합니다.

#

명령:

p, = 사용 커밋 선택

r, reword = commit을 사용하지만 commit 메시지를 편집합니다.

e, 편집 = 커밋을 사용하지만 수정하려면 중지합니다.

s, squash = commit을 사용하지만 이전 커밋에 혼합됩니다.

f, "fix"와 같이 =를 수정하지만 이 커밋의 로그 메시지는 삭제합니다.

x, exec = 셸을 사용하여 명령 실행(나머지 줄)

d, drop = 커밋 제거

#

이러한 라인은 순서를 다시 지정할 수 있으며, 위에서 아래로 실행됩니다.

#

여기서 한 줄을 제거하면 커밋이 손실됩니다.

#

그러나 모든 항목을 제거하면 기본 재배치가 중단됩니다.

#

빈 커밋이 코멘트 아웃된다는 점에 유의하십시오.

~
~
~
~
~
~
~
~
~

여기서 필요에 따라 첫 번째 줄을 변경합니다(위에 나열된 명령을 사용하여 커밋 등을 제거).편집이 완료되면 ':x'를 눌러 편집기를 저장하고 종료합니다(vim 편집기 전용).

그리고 나서.

기트 푸쉬

문제가 나타나면 원격으로 변경사항을 강제로 푸시해야 합니다.ITS 매우 중요: 팀에서 작업 중인 경우 무리하게 밀지 마십시오.

git push -f 원점

이것은 깃체리픽으로 하시면 됩니다.'commit-pick'은 지금 분기에 커밋을 적용합니다.

그럼 하시오

git rebase --hard <SHA1 of A>

그런 다음 D 및 E 커밋을 적용합니다.

git cherry-pick <SHA1 of D>
git cherry-pick <SHA1 of E>

이것은 B와 C 커밋을 건너뛸 것입니다.B가 없으면 지점에 D 커밋을 적용하는 것이 불가능할 수 있으니 YMMV.

언급URL : https://stackoverflow.com/questions/495345/how-to-remove-selected-commit-log-entries-from-a-git-repository-while-keeping-th

반응형