과거에 두 개의 임의 커밋 사이에 커밋을 삽입하는 방법은 무엇입니까? 있다고 가정합니다. A — B — C A과 사이에

로컬 전용 브랜치에 다음 커밋 기록이 있다고 가정합니다.

A -- B -- C

A과 사이에 새 커밋을 어떻게 삽입 B합니까?



답변

OP의 답변보다 훨씬 쉽습니다.

  1. git rebase -i <any earlier commit>. 구성된 텍스트 편집기에 커밋 목록이 표시됩니다.
  2. 삽입하려는 커밋을 찾습니다 (라고 가정 해 보겠습니다 a1b2c3d). 편집기에서 해당 줄에 pick대해 edit.
  3. 텍스트 편집기를 닫아 리베이스를 시작하십시오 (변경 사항 저장). 이렇게하면 방금 커밋 된 것처럼 이전에 선택한 커밋 ( a1b2c3d) 이있는 명령 프롬프트가 표시 됩니다.
  4. 변경하고 git commit( 대부분 의 경우와 달리 수정 하지 않음edit ). 이렇게 하면 선택한 커밋 뒤에 새 커밋이 생성 됩니다.
  5. git rebase --continue. 그러면 연속 커밋이 재생되고 새 커밋이 올바른 위치에 삽입됩니다.

이것은 역사를 다시 쓰게 될 것이고, 당기려고하는 다른 사람을 깨뜨릴 것이라는 점에주의하십시오.


답변

여기에 있는 답은 매우 간단 합니다 . 지점에 있다고 가정합니다 branch. 다음 단계를 수행하십시오.

  • 새 커밋 (이 경우 commit A) 을 삽입하려는 후 커밋에서 임시 분기를 만듭니다 .

    git checkout -b temp A
    
  • 변경 사항을 수행하고 커밋하고 커밋을 생성하고 호출합시다 N.

    git commit -a -m "Message"
    

    (또는 git add뒤에 git commit)

  • 새 커밋 이후에 원하는 커밋 (이 경우에는 커밋 BC)을 새 커밋으로 리베이스합니다 .

    git rebase temp branch
    

(아마도 ciekawy에 의해 더 이상 존재하지 않는 주석-p 덕분에 병합을 보존 하기 위해 사용해야 합니다 )

  • 임시 분기를 삭제하십시오.

    git branch -d temp
    

그 후의 역사는 다음과 같습니다.

A -- N -- B -- C

물론 리베이스하는 동안 일부 충돌이 나타날 수 있습니다.

지점이 로컬 전용이 아닌 경우 다시 쓰기 기록이 발생하므로 심각한 문제가 발생할 수 있습니다.


답변

더 쉬운 솔루션 :

  1. 마지막에 새 커밋 D를 만듭니다. 이제 다음을 수행합니다.

    A -- B -- C -- D
    
  2. 그런 다음 다음을 실행하십시오.

    $ git rebase -i hash-of-A
    
  3. Git이 편집기를 열면 다음과 같이 표시됩니다.

    pick 8668d21 B
    pick 650f1fc C
    pick 74096b9 D
    
  4. 이렇게 D를 맨 위로 옮기고 저장하고 종료

    pick 74096b9 D
    pick 8668d21 B
    pick 650f1fc C
    
  5. 이제 다음을 갖게됩니다.

    A -- D -- B -- C
    

답변

커밋 히스토리가라고 가정하고 와 preA -- A -- B -- C사이에 커밋을 삽입하려는 경우 단계는 다음과 같습니다.AB

  1. git rebase -i hash-of-preA

  2. Git이 편집기를 엽니 다. 내용은 다음과 같을 수 있습니다.

    pick 8668d21 A
    pick 650f1fc B
    pick 74096b9 C
    

    첫 번째 pickedit다음으로 변경하십시오 .

    edit 8668d21 A
    pick 650f1fc B
    pick 74096b9 C
    

    저장하고 종료.

  3. 코드를 수정 한 다음 git add . && git commit -m "I"

  4. git rebase --continue

이제 Git 커밋 기록은 preA -- A -- I -- B -- C


충돌이 발생하면 Git은이 커밋에서 중지됩니다. 를 사용 git diff하여 충돌 마커를 찾아 해결할 수 있습니다. 모든 충돌을 해결 한 후에는을 사용 git add <filename>하여 충돌이 해결되었음을 Git에 알리고 git rebase --continue.

rebase를 실행 취소하려면 git rebase --abort.


답변

내가 읽은 다른 답변에서 볼 수있는 리베이스 동안 “편집 해킹”을 피하는 전략이 있습니다.

를 사용 git rebase -i하면 해당 커밋 이후 커밋 목록을 얻을 수 있습니다. 파일 상단에 “중단”을 추가하면 해당 지점에서 리베이스가 중단됩니다.

break
pick <B's hash> <B's commit message>
pick <C's hash> <C's commit message>

일단 시작되면 git rebase이제 “휴식”지점에서 멈 춥니 다. 이제 파일을 편집하고 정상적으로 커밋을 만들 수 있습니다. 그런 다음을 사용하여 리베이스를 계속할 수 있습니다 git rebase --continue. 이로 인해 해결해야 할 충돌이 발생할 수 있습니다. 길을 잃은 경우 항상 사용을 중단 할 수 있음을 잊지 마십시오 git rebase --abort.

이 전략은 커밋을 어디에 든 삽입하도록 일반화 할 수 있습니다. 커밋을 삽입하려는 지점에 “중단”을두기 만하면됩니다.

역사를 다시 쓴 후에는 git push -f. 브랜치를 가져 오는 다른 사람들에 대한 일반적인 경고가 적용됩니다.


답변

여기에 이미 많은 좋은 답변이 있습니다. 간단한 4 단계로 “리베이스 없음”솔루션을 추가하고 싶었습니다.


요약

git checkout A
git commit -am "Message for commit D"
git cherry-pick A..C
git branch -f master HEAD

설명

(참고 :이 솔루션의 한 가지 장점은 최종 결과에 대해 100 % 확신 할 때 최종 단계까지 분기를 건드리지 않으므로 매우 편리한 “사전 확인”단계가 있다는 것입니다. AB 테스트 허용 .)


초기 상태 ( master지점 이름으로 가정 했습니다)

A -- B -- C <<< master <<< HEAD

1) 올바른 위치에서 HEAD를 가리키는 것으로 시작

git checkout A

     B -- C <<< master
    /
   A  <<< detached HEAD

(선택적으로 여기에서 HEAD를 분리하는 대신을 사용하여 임시 분기를 만들 수 있습니다.이 분기 git checkout -b temp A는 프로세스가 끝날 때 삭제해야합니다. 다른 모든 변형은 동일하게 유지되므로 원하는대로 작동합니다.)


2) 삽입 할 새 커밋 D 생성

# at this point, make the changes you wanted to insert between A and B, then

git commit -am "Message for commit D"

     B -- C <<< master
    /
   A -- D <<< detached HEAD (or <<< temp <<< HEAD)

3) 그런 다음 마지막 누락 된 커밋 B와 C의 복사본을 가져옵니다 (커밋이 더 있으면 같은 줄이됩니다).

git cherry-pick A..C

# (if any, resolve any potential conflicts between D and these last commits)

     B -- C <<< master
    /
   A -- D -- B' -- C' <<< detached HEAD (or <<< temp <<< HEAD)

(필요한 경우 여기에서 편안한 AB 테스트)

이제 요구 사항을 테스트 할 것을 코드, 테스트 아무것도를 검사하는 순간, 당신은 또한 DIFF / 비교 / 검사 할 수 있습니다 당신이 무엇을했다 무엇을 얻을 것입니다 작업 후.


4)C 와 사이의 테스트에 따라 C'OK 또는 KO입니다.

(어느 한 쪽) 4-OK) 마지막으로master

git branch -f master HEAD

     B -- C <<< (B and C are candidates for garbage collection)
    /
   A -- D -- B' -- C' <<< master

(또는) 4-KO) 그냥 떠날 master변경

임시 브랜치를 생성했다면 git branch -d <name> ,하지만 당신은 분리 된 HEAD 경로에 들어갑니다 경우,이 시점에서 전혀 필요하지 동작은 새로운 커밋은 다시 연결 직후 가비지 컬렉션을받을 수 없습니다 HEAD로모그래퍼git checkout master

두 경우 모두 (OK 또는 KO)이 시점에서 master다시 체크 아웃 하여 HEAD.


답변