programing

Git에서 처음 두 개의 커밋을 뭉개시겠습니까?

padding 2023. 4. 18. 21:50
반응형

Git에서 처음 두 개의 커밋을 뭉개시겠습니까?

와 함께git rebase --interactive <commit>임의의 수의 커밋을 하나의 커밋으로 압축할 수 있습니다.

처음 약속에 끼워넣고 싶지 않다면 그건 다 좋은 일이야.그건 불가능할 것 같아요.

그것을 달성할 수 있는 방법이 있나요?


중간 정도 관련:

관련 질문에서 저는 첫 번째 약속, 즉 두 번째 약속과 충돌해야 하는 필요성에 대해 다른 접근법을 생각해 냈습니다.

관심 있는 경우: git: 커밋을 처음 삽입하고 다른 모든 커밋을 옮기는 방법

2012년 7월 갱신 (git 1.7.12+)

이제 루트까지 모든 커밋을 기본 재배치하고 두 번째 커밋을 선택할 수 있습니다.Y선두에 눌리다X.

git rebase -i --root master

pick sha1 X
squash sha1 Y
pick sha1 Z
git rebase [-i] --root $tip

이제 이 명령어를 사용하여 "에서 시작하는 모든 이력을 다시 쓸 수 있습니다.$tiproot commit까지.

Chris Web()arachsysGitHub에서 commit df5df20c13(rebase -i: support --root without --onto, 2012-06-26)을 참조하십시오.

코멘트에 기재된 바와 같이 (보다 안전)--force Mikko Mantalainen reminds us)가 필요하기 때문입니다.rebase조작(리모트저장소에서 재작업을 퍼블리시해야 하는 경우)


원답(2009년 2월)

SO 질문 "Git 저장소의 처음 커밋을 결합하는 방법"에서 다른 레시피를 찾을 수 있을 것입니다.

Charles Bailey는 거기서 가장 상세한 답을 제시했습니다.커밋은 (이전 주와의 차이뿐만 아니라) 풀 트리임을 상기시켜 줍니다.
여기서 오래된 커밋('초기 커밋')과 새로운 커밋(파쇄 결과)은 공통의 조상을 가지지 않습니다.
즉, 할 수 없습니다.commit --amend첫 번째 커밋을 새로운 커밋으로 변환한 후 새로운 커밋으로 이전 커밋 이력(경합 발생)을 다시 설정합니다.

(마지막 문장은 더 이상 해당되지 않습니다.)git rebase -i --root <aBranch>)

오히려 (와 함께)A원래의 「초기 커밋」과B후속 커밋을 최초 커밋으로 압축해야 합니다.)

  1. 초기 커밋을 형성하는 마지막 커밋으로 돌아갑니다(HEAD 분리).

    git checkout <sha1_for_B>
    
  2. 분기 포인터를 초기 커밋으로 리셋하고 인덱스와 작업 트리는 그대로 둡니다.

    git reset --soft <sha1_for_A>
    
  3. 'B'의 트리를 사용하여 초기 트리를 수정합니다.

    git commit --amend
    
  4. 이 새로운 초기 커밋에 일시적으로 태그를 붙입니다(또는 새로운 커밋 sha1을 수동으로 기억할 수도 있습니다).

    git tag tmp
    
  5. 원래 브랜치로 돌아갑니다(이 예에서는 마스터로 가정합니다).

    git checkout master
    
  6. B 이후의 모든 커밋을 새로운 초기 커밋으로 재생합니다.

    git rebase --onto tmp <sha1_for_B>
    
  7. 임시 태그를 제거합니다.

    git tag -d tmp
    

「아, 아, 아, 아, 아, 아, 아, 아, 아, 네.rebase --onto마지막 커밋 후 작성된 이력을 다시 작성하기 때문에 Marge 중 경합은 발생하지 않습니다( ).B 뭉개다A부터 )까지tmp(파쇄된 새로운 커밋을 나타냄): 간단한 패스트포워드 머지만.

'일부러'에이 됩니다.A-B '''도 마찬가지A-...-...-...-B도 이 첫 할 수 .)

단순히 모든 커밋을 하나의 초기 커밋으로 압축하는 경우 저장소를 리셋하고 첫 번째 커밋을 수정합니다.

git reset hash-of-first-commit
git add -A
git commit --amend

Git reset은 작업 트리를 그대로 유지하므로 모든 것이 그대로 유지됩니다.git add 명령을 사용하여 파일을 추가하고 이러한 변경으로 첫 번째 커밋을 수정하십시오.rebase -i와 비교하면 git 코멘트를 Marge할 수 없습니다.

저는 VonC의 스크립트를 수정하여 모든 것을 자동으로 수행하도록 하고 아무것도 요구하지 않습니다.두 개의 커밋 SHA1을 지정하면 그 사이의 모든 것이 "파쇄된 이력"이라는 하나의 커밋으로 압축됩니다.

#!/bin/sh
# Go back to the last commit that we want
# to form the initial commit (detach HEAD)
git checkout $2

# reset the branch pointer to the initial commit (= $1),
# but leaving the index and working tree intact.
git reset --soft $1

# amend the initial tree using the tree from $2
git commit --amend -m "squashed history"

# remember the new commit sha1
TARGET=`git rev-list HEAD --max-count=1`

# go back to the original branch (assume master for this example)
git checkout master

# Replay all the commits after $2 onto the new initial commit
git rebase --onto $TARGET $2

중요한 것은 저장소의 유일한 것은 빈 .gitignore인 "no-op" 첫 번째 커밋을 작성함으로써 이 문제를 회피하는 것입니다.

https://github.com/DarwinAwardWinner/git-custom-commands/blob/master/bin/git-myinit

그렇게 하면 첫 번째 약속을 망칠 이유가 없어.

이렇게 하면 두 번째 커밋이 첫 번째 커밋으로 압축됩니다.

A-B-C-... -> AB-C-...

git filter-branch --commit-filter '
    if [ "$GIT_COMMIT" = <sha1ofA> ];
    then
        skip_commit "$@";
    else
        git commit-tree "$@";
    fi
' HEAD

AB에 대한 커밋 메시지는 B에서 가져옵니다(A가 좋습니다).

Uwe Kleine-König의 답변과 동일한 효과가 있지만, 비초기 A에도 적용됩니다.

첫 번째 커밋과 두 번째 커밋을 뭉개면 첫 번째 커밋이 다시 작성됩니다.첫 번째 커밋에 기반한 브랜치가 여러 개 있는 경우 해당 브랜치를 절단합니다.

다음 예를 생각해 보겠습니다.

a---b---HEAD
 \
  \
   '---d

a와 b를 새로운 커밋 "ab"로 압축하면 두 개의 서로 다른 트리가 생성되며, 대부분의 경우 git-mergegit-rebase는 두 브랜치에서 더 이상 작동하지 않기 때문에 바람직하지 않습니다.

ab---HEAD

a---d

네가 정말 이걸 원한다면, 할 수 있어.git-filter-branch에서 이력 개서를 위한 강력한(위험한) 도구를 확인하십시오.

이를 위해 git filter-branch를 사용할 수 있습니다.

git filter-branch --parent-filter \
'if test $GIT_COMMIT != <sha1ofB>; then cat; fi'

그 결과 AB-C는 A의 커밋 로그를 폐기합니다.

rebase interactive를 사용하여 리모트로 푸시되기 전에 마지막 두 개의 커밋을 수정할 수 있습니다.

git rebase HEAD^^ -i

이치노릇을 하다를 들어, 여러분이 지금 이 에 있다고 해 보겠습니다.master

모든 커밋 기록을 삭제하는 새로운 고립된 분기를 만듭니다.

$ git checkout --orphan new_branch

첫 번째 커밋 메시지를 추가합니다.

$ git commit -a

병합되지 않은 오래된 마스터 브랜치를 삭제합니다.

$ git branch -D master

의 브랜치 이름을 변경합니다.new_branch로로 합니다.master:

$ git branch -m master

언급URL : https://stackoverflow.com/questions/598672/squash-the-first-two-commits-in-git

반응형