IT story

자식 기록에서 특정 개정을 어떻게 제거합니까?

hot-time 2020. 5. 1. 08:07
반응형

자식 기록에서 특정 개정을 어떻게 제거합니까?


git history가 다음과 같다고 가정하십시오.

12 34 5

1–5는 별도의 개정판입니다. 1, 2, 4 및 5를 계속 유지하면서 3을 제거해야합니다. 어떻게해야합니까?

삭제 후 수백 개의 개정이있을 때 효율적인 방법이 있습니까?


개정판 3과 4를 단일 개정판으로 결합하기 위해 git rebase를 사용할 수 있습니다. 개정 3의 변경 사항을 제거하려면 대화식 리베이스 모드에서 편집 명령을 사용해야합니다. 변경 사항을 단일 개정으로 결합하려면 squash를 사용하십시오.

이 스쿼시 기법을 성공적으로 사용했지만 이전에 개정판을 제거 할 필요는 없었습니다. "Splitting commits"아래의 git-rebase 문서는이를 이해하기에 충분한 아이디어를 제공 할 것입니다. 또는 다른 사람이 알고있을 수도 있습니다.

로부터 자식 문서 :

그대로 유지하려는 가장 오래된 커밋으로 시작하십시오.

git rebase -i <after-this-commit>

주어진 커밋 뒤에 오는 현재 분기의 모든 커밋 (병합 커밋 무시)으로 편집기가 시작됩니다. 이 목록의 커밋을 마음의 내용으로 재정렬하고 제거 할 수 있습니다. 목록은 다음과 같이 다소 비슷합니다.

deadbee를 선택하십시오이 커밋의 한 줄
다음 커밋의 한 줄
...

oneline 설명은 순전히 당신의 즐거움을위한 것입니다. git-rebase는 커밋 이름 (이 예제에서는 "deadbee"및 "fa1afe1")을 보지 않으므로 이름을 삭제하거나 편집하지 마십시오.

"pick"명령을 "edit"명령으로 대체하면 커밋을 적용한 후 git-rebase에게 중지하도록 지시하여 파일 및 / 또는 커밋 메시지를 편집하고 커밋을 수정 한 후 재베이스 작업을 계속할 수 있습니다.

둘 이상의 커밋을 하나로 묶으려면 두 번째 이후 커밋에 대해 "pick"명령을 "squash"로 바꾸십시오. 커밋에 다른 작성자가있는 경우 스쿼시 된 커밋이 첫 번째 커밋의 작성자에게 기인합니다.


다음은 제거하려는 대상 <commit-id>만 알고 비 대화식으로 특정을 제거하는 방법입니다 <commit-id>.

git rebase --onto <commit-id>^ <commit-id> HEAD

이 의견에 따르면 (그리고 이것이 사실인지 확인) rado의 대답은 매우 가깝지만 git을 분리 된 헤드 상태로 둡니다. 대신, HEAD이것을 제거 하고 사용하여 현재 <commit-id>지점에서 제거하십시오 .

git rebase --onto <commit-id>^ <commit-id>

앞에서 언급했듯이 git-rebase (1) 는 당신의 친구입니다. 커밋이 master지점 에 있다고 가정하면 다음을 수행합니다.

git rebase --onto master~3 master~2 master

전에:

1---2---3---4---5  master

후:

1---2---4'---5' master

git-rebase (1)에서 :

rebase를 사용하여 커밋 범위를 제거 할 수도 있습니다. 다음과 같은 상황이 발생하면

E---F---G---H---I---J  topicA

그런 다음 명령

git rebase --onto topicA~5 topicA~3 topicA

커밋 F와 G가 제거됩니다.

E---H'---I'---J'  topicA

이는 F와 G에 어떤 방식으로 결함이 있거나 주제 A의 일부가 아니어야하는 경우에 유용합니다. --onto에 대한 인수와 매개 변수는 유효한 commit-ish 일 수 있습니다.


개정 3에서 변경 한 내용을 제거하기 만하면 git revert를 사용할 수 있습니다.

힘내 되돌리기는 단순히 되 돌리는 개정의 모든 변경 사항을 취소하는 변경 사항으로 새 개정을 만듭니다.

이것은 원하지 않는 커밋과 해당 변경 사항을 제거하는 커밋에 대한 정보를 유지한다는 의미입니다.

되돌리기는 기본적으로 표준 커밋이기 때문에 누군가가 저장소에서 가져 온 것이 가능하다면 훨씬 더 친숙 할 것입니다.


지금까지의 모든 답변은 후행 문제를 다루지 않습니다.

삭제 후 수백 개의 개정이있을 때 효율적인 방법이 있습니까?

단계는 다음과 같지만 참조 용으로 다음과 같은 기록을 가정 해 보겠습니다.

[master] -> [hundreds-of-commits-including-merges] -> [C] -> [R] -> [B]

C : 커밋을 제거한 직후 커밋을 제거하십시오 (깨끗한 상태)

R : 제거 할 커밋

B : 커밋을 제거하기 직전에 커밋을 제거하십시오 (기본)

Because of the "hundreds of revisions" constraint, I'm assuming the following pre-conditions:

  1. there is some embarrassing commit that you wish never existed
  2. there are ZERO subsequent commits that actually depend on that embarassing commit (zero conflicts on revert)
  3. you don't care that you will be listed as the 'Committer' of the hundreds of intervening commits ('Author' will be preserved)
  4. you have never shared the repository
    • or you actually have enough influence over all the people who have ever cloned history with that commit in it to convince them to use your new history
    • and you don't care about rewriting history

This is a pretty restrictive set of constraints, but there is an interesting answer that actually works in this corner case.

Here are the steps:

  1. git branch base B
  2. git branch remove-me R
  3. git branch save
  4. git rebase --preserve-merges --onto base remove-me

If there are truly no conflicts, then this should proceed with no further interruptions. If there are conflicts, you can resolve them and rebase --continue or decide to just live with the embarrassment and rebase --abort.

Now you should be on master that no longer has commit R in it. The save branch points to where you were before, in case you want to reconcile.

How you want to arrange everyone else's transfer over to your new history is up to you. You will need to be acquainted with stash, reset --hard, and cherry-pick. And you can delete the base, remove-me, and save branches


So here is the scenario that I faced, and how I solved it.

[branch-a]

[Hundreds of commits] -> [R] -> [I]

here R is the commit that I needed to be removed, and I is a single commit that comes after R

I made a revert commit and squashed them together

git revert [commit id of R]
git rebase -i HEAD~3

During the interactive rebase squash the last 2 commits.


I also landed in a similar situation. Use interactive rebase using the command below and while selecting, drop 3rd commit.

git rebase -i remote/branch

Answers of rado and kareem do nothing for me (only message "Current branch is up to date." appears). Possibly this happens because '^' symbol doesn't work in Windows console. However, according to this comment, replacing '^' by '~1' solves the problem.

git rebase --onto <commit-id>^ <commit-id>

To remove old commit history from git repo:

First run below cmd

rm -rf .git

-- recreate repo from current

git init                                                                           
git add .                                                  
git commit -m "first commit"

-- push to the github remote repos

git remote add origin git@github.com<your git mail>   
git push -u --force origin master

참고URL : https://stackoverflow.com/questions/37219/how-do-you-remove-a-specific-revision-in-the-git-history

반응형