이전 커밋을 여러 커밋으로 나누기 로컬 저장소에

지점을 만들지 않고 새 지점에서 펑키 작업을 많이 수행하지 않으면 로컬 저장소에 커밋 된 후 단일 커밋을 몇 가지 커밋으로 나눌 수 있습니까?



답변

git rebase -i 할 것입니다.

먼저 깨끗한 작업 디렉토리로 시작하십시오. git status보류중인 수정, 삭제 또는 추가가 표시되지 않아야합니다.

이제 분할하려는 커밋을 결정해야합니다.

A) 가장 최근 커밋 나누기

가장 최근의 커밋을 분리하려면 먼저 :

$ git reset HEAD~

이제 평소와 같이 조각을 개별적으로 커밋하여 필요한만큼 커밋을 만듭니다.

B) 커밋을 더 멀리 나누기

이를 위해서는 rebasing , 즉 기록을 다시 작성 해야합니다 . 올바른 커밋을 찾으려면 몇 가지 선택 사항이 있습니다.

  • 다시 세 번 커밋했다면

    $ git rebase -i HEAD~3
    

    어디 3그것이 다시 얼마나 많은 커밋이다.

  • 당신이 계산하고 싶은 것보다 나무에서 더 멀리 있었다면

    $ git rebase -i 123abcd~
    

    123abcd분할하려는 커밋의 SHA1은 어디에 있습니까 ?

  • 마스터로 병합하려는 다른 지점 (예 : 기능 지점)에있는 경우 :

    $ git rebase -i master
    

리베이스 편집 화면이 나타나면 분리하려는 커밋을 찾으십시오. 그 라인의 시작 부분에서, 교체 pickedit( e짧은). 버퍼를 저장하고 종료하십시오. Rebase는 편집하려는 커밋 직후 중지됩니다. 그때:

$ git reset HEAD~

일반적인 방식으로 조각을 커밋하고 필요한만큼 커밋을 만든 다음

$ git rebase --continue

답변

에서 자식-REBASE의 매뉴얼 (분할 섹션 커밋)

대화식 모드에서 “edit”조치로 커미트를 표시 할 수 있습니다. 그러나 이것이 반드시 git rebase 가이 편집의 결과가 정확히 하나의 커밋 일 것으로 기대한다는 것을 의미하지는 않습니다. 실제로 커밋을 취소하거나 다른 커밋을 추가 할 수 있습니다. 커밋을 두 개로 나누는 데 사용할 수 있습니다.

  • 와 상호 작용하는 REBASE 시작 git rebase -i <commit>^, <commit>당신이 분할 할 커밋됩니다. 실제로, 해당 커밋이 포함되어있는 한 모든 커밋 범위가 수행됩니다.

  • “edit”조치로 분할하려는 커밋을 표시하십시오.

  • 커밋을 편집 할 때 실행하십시오 git reset HEAD^. 그 결과 HEAD가 1 개씩 되 감겨지고 인덱스가 적합합니다. 그러나 작업 트리는 동일하게 유지됩니다.

  • 이제 첫 번째 커밋에서 갖고 싶은 인덱스에 변경 사항을 추가하십시오. 당신은 사용할 수 있습니다 git add(가능한 대화 형) 또는 git gui(또는 둘 다) 그렇게 할 수 있습니다.

  • 현재 적절한 커밋 메시지로 현재 인덱스를 커밋하십시오.

  • 작업 트리가 깨끗해질 때까지 마지막 두 단계를 반복하십시오.

  • 로 리베이스를 계속하십시오 git rebase --continue.


답변

사용 git rebase --interactive이전 커밋 실행 편집에 git reset HEAD~다음, 그리고 git add -p다음 몇 가지 더 추가 한 다음 커밋 할 몇 가지를 추가하고 다른 당신 같은 수만큼, 커밋 확인합니다. 완료되면를 실행 git rebase --continue하면 스택의 모든 분할 커밋이 이전에 시작됩니다.

중대한 : 당신은 항상 실행할 수 있기 때문에 당신은 오래된 변경을 잃어 버릴까 걱정에 놀러와 당신이 원하는 모든 변경 사항을 확인하지있을 수 있습니다 git reflog원하는 변경 사항이 포함되어 프로젝트의 지점을 찾기 위해, (현실을 부르 자 a8c4ab) 다음 git reset a8c4ab.

작동 방식을 보여주는 일련의 명령은 다음과 같습니다.

mkdir git-test; cd git-test; git init

이제 파일을 추가하십시오 A

vi A

이 줄을 추가하십시오 :

one

git commit -am one

그런 다음이 줄을 A에 추가하십시오.

two

git commit -am two

그런 다음이 줄을 A에 추가하십시오.

three

git commit -am three

이제 파일 A는 다음과 같습니다.

one
two
three

그리고 우리 git log 는 다음과 같이 보입니다.git log --pretty=oneline --pretty="%h %cn %cr ---- %s"

bfb8e46 Rose Perrone 4 seconds ago ---- three
2b613bc Rose Perrone 14 seconds ago ---- two
9aac58f Rose Perrone 24 seconds ago ---- one

두 번째 커밋을 나누고 싶다고 가정 해 봅시다. two .

git rebase --interactive HEAD~2

다음과 같은 메시지가 나타납니다.

pick 2b613bc two
pick bfb8e46 three

커밋을 편집하려면 첫 번째 pick를로 변경하십시오 e.

git reset HEAD~

git diff 우리는 두 번째 커밋에 대해 커밋을 단계적으로 해제했음을 보여줍니다.

diff --git a/A b/A
index 5626abf..814f4a4 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
 one
+two

변경 사항을 준비하고 file의 해당 줄에 “및 세 번째”를 추가합시다 A.

git add .

이것은 보통 대화식 rebase 동안 실행할 시점입니다 git rebase --continue. 왜냐하면 보통 커밋 스택으로 돌아가서 이전 커밋을 편집하기 때문입니다. 그러나 이번에는 새로운 커밋을 만들고 싶습니다. 그래서 우리는 실행할 것 git commit -am 'two and a third'입니다. 이제 파일을 편집 A하고 행을 추가합니다 two and two thirds.

git add .
git commit -am 'two and two thirds'
git rebase --continue

커밋과 충돌이 three있으므로 해결해 보겠습니다.

우리는 변할거야

one
<<<<<<< HEAD
two and a third
two and two thirds
=======
two
three
>>>>>>> bfb8e46... three

one
two and a third
two and two thirds
three

git add .; git rebase --continue

이제 우리 git log -p는 다음과 같이 보입니다 :

commit e59ca35bae8360439823d66d459238779e5b4892
Author: Rose Perrone <roseperrone@fake.com>
Date:   Sun Jul 7 13:57:00 2013 -0700

    three

diff --git a/A b/A
index 5aef867..dd8fb63 100644
--- a/A
+++ b/A
@@ -1,3 +1,4 @@
 one
 two and a third
 two and two thirds
+three

commit 4a283ba9bf83ef664541b467acdd0bb4d770ab8e
Author: Rose Perrone <roseperrone@fake.com>
Date:   Sun Jul 7 14:07:07 2013 -0700

    two and two thirds

diff --git a/A b/A
index 575010a..5aef867 100644
--- a/A
+++ b/A
@@ -1,2 +1,3 @@
 one
 two and a third
+two and two thirds

commit 704d323ca1bc7c45ed8b1714d924adcdc83dfa44
Author: Rose Perrone <roseperrone@fake.com>
Date:   Sun Jul 7 14:06:40 2013 -0700

    two and a third

diff --git a/A b/A
index 5626abf..575010a 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
 one
+two and a third

commit 9aac58f3893488ec643fecab3c85f5a2f481586f
Author: Rose Perrone <roseperrone@fake.com>
Date:   Sun Jul 7 13:56:40 2013 -0700

    one

diff --git a/A b/A
new file mode 100644
index 0000000..5626abf
--- /dev/null
+++ b/A
@@ -0,0 +1 @@
+one

답변

이전 답변에서는 git rebase -i분할하려는 커밋을 편집하고 커밋하는 부분 을 다루었습니다 .

이것은 파일을 다른 커밋으로 분할 할 때 잘 작동하지만 개별 파일의 변경 사항을 나누려면 더 알아야 할 것이 있습니다.

를 사용 rebase -i하고 표시하기 위해 커밋하려는 커밋에 edit두 가지 옵션이 있습니다.

  1. 를 사용한 후 각 커밋에서 원하는 git reset HEAD~패치 git add -p를 선택하기 위해 개별적으로 패치를 사용 하십시오.

  2. 작업 사본을 편집하여 원하지 않는 변경 사항을 제거하십시오. 그 중간 상태를 저 지르십시오. 그리고 다음 라운드에 대한 전체 커밋을 취소하십시오.

옵션 2는 임시 커밋을 분할 할 때 유용합니다. 이는 중간 버전이 병합의 일부로 올바르게 빌드되고 실행되는지 확인할 수 있기 때문입니다. 이것은 다음과 같이 진행됩니다.

커밋을 사용 rebase -i하고 사용한 후에 edit

git reset --soft HEAD~

커밋을 취소하지만 커밋 된 파일을 인덱스에 그대로 둡니다. 초기 커밋이 최종 결과에 얼마나 가까운 지에 따라 –soft를 생략하여 혼합 재설정을 수행 할 수도 있습니다. 유일한 차이점은 모든 변경 사항을 단계별로 시작하는지 또는 모든 단계를 거치지 않은 상태로 시작하는 것입니다.

이제 코드를 편집하십시오. 변경 사항을 제거하고 추가 된 파일을 삭제하며 원하는 시리즈의 첫 번째 커밋을 구성하려는 모든 작업을 수행 할 수 있습니다. 또한 빌드하고 실행하며 일관된 소스 세트가 있는지 확인할 수 있습니다.

행복하면 파일을 필요에 따라 준비 / 언 스테이지하고 ( git gui이 용도로 사용 하고 싶습니다 ) UI 또는 명령 줄을 통해 변경 사항을 커밋합니다.

git commit

이것이 첫 번째 커밋입니다. 이제 작업 사본을 분할 한 커밋 이후의 상태로 복원하여 다음 커밋에 대해 더 많은 변경 사항을 적용 할 수 있습니다. 편집중인 커밋의 sha1을 찾으려면을 사용하십시오 git status. 상태의 처음 몇 줄에는 현재 실행중인 rebase 명령이 표시되어 원래 커밋의 sha1을 찾을 수 있습니다.

$ git status
interactive rebase in progress; onto be83b41
Last commands done (3 commands done):
   pick 4847406 US135756: add debugging to the file download code
   e 65dfb6a US135756: write data and download from remote
  (see more in file .git/rebase-merge/done)
...

이 경우 편집중인 커밋에는 sha1이 65dfb6a있습니다. 이를 알면 git checkout커밋과 파일 위치를 모두 사용하는 형식을 사용하여 작업 디렉토리에서 커밋 내용을 확인할 수 있습니다. 여기 .에서 전체 작업 복사본을 대체 할 파일 위치로 사용 합니다.

git checkout 65dfb6a .

끝에 점을 놓치지 마세요!

이렇게하면 편집중인 커밋 이후의 파일을 체크 아웃하고 준비하지만 이전 커밋과 관련이 있으므로 이미 커밋 한 변경 내용은 커밋에 포함되지 않습니다.

이제 다른 분할 커밋을 만들기 전에 커밋의 일부를 삭제하고 분할을 마치기 위해 그대로 커밋하거나 다시 돌아갈 수 있습니다.

하나 이상의 커밋에 원래 커밋 메시지를 재사용하려면 rebase의 작업 파일에서 바로 사용할 수 있습니다.

git commit --file .git/rebase-merge/message

마지막으로 모든 변경 사항을 커밋하면

git rebase --continue

리베이스 작업을 수행하고 완료합니다.


답변

git rebase --interactive커밋을 더 작은 커밋으로 분할하는 데 사용할 수 있습니다. rebaseGit 문서는 프로세스를 간략하게 설명합니다-커밋 분할 :

대화식 모드에서 “edit”조치로 커미트를 표시 할 수 있습니다. 그러나 git rebase이것이 반드시이 편집 결과가 정확히 하나의 커밋이 될 것으로 예상하는 것은 아닙니다 . 실제로 커밋을 취소하거나 다른 커밋을 추가 할 수 있습니다. 커밋을 두 개로 나누는 데 사용할 수 있습니다.

  • 와 상호 작용하는 REBASE 시작 git rebase -i <commit>^, <commit>당신이 분할 할 커밋됩니다. 실제로, 해당 커밋이 포함되어있는 한 모든 커밋 범위가 수행됩니다.

  • “edit”조치로 분할하려는 커밋을 표시하십시오.

  • 커밋을 편집 할 때 실행하십시오 git reset HEAD^. 그 결과 HEAD가 1 개씩 되 감겨지고 인덱스가 적합합니다. 그러나 작업 트리는 동일하게 유지됩니다.

  • 이제 첫 번째 커밋에서 갖고 싶은 인덱스에 변경 사항을 추가하십시오. 당신은 사용할 수 있습니다 git add(가능한 대화 형) 또는 자식 GUI (또는 둘 다) 그렇게 할 수 있습니다.

  • 현재 적절한 커밋 메시지로 현재 인덱스를 커밋하십시오.

  • 작업 트리가 깨끗해질 때까지 마지막 두 단계를 반복하십시오.

  • 로 리베이스를 계속하십시오 git rebase --continue.

중간 개정판이 일관성이 있는지 확실하지 않은 경우 (컴파일, 테스트 슈트 등을 전달) git stash각 커밋, 테스트 및 수정이 필요한 경우 커밋을 수정 한 후에 아직 커밋되지 않은 변경 사항을 제거하는 데 사용해야합니다. .


답변

이제 Windows의 최신 TortoiseGit에서 매우 쉽게 할 수 있습니다.

rebase 대화 상자를 열고 구성한 후 다음 단계를 수행하십시오.

  • 분할하려는 커밋을 마우스 오른쪽 단추로 클릭하고 ” Edit“(픽, 스쿼시, 삭제 중)를 선택하십시오.
  • Start“을 (를) 클릭 하여 리베이스를 시작 하십시오 .
  • 분할 커밋에 도달하면 ” Edit/Split“버튼을 확인하고 ” Amend“를 직접 클릭하십시오 . 커밋 대화 상자가 열립니다.
  • 별도의 커밋에 넣을 파일을 선택 해제하십시오.
  • 커밋 메시지를 편집 한 다음 “commit ” .
  • 커밋 할 파일이있을 때까지 커밋 대화 상자가 계속해서 열립니다. 커밋 할 파일이 더 이상 없어도 커밋을 하나 더 추가할지 묻는 메시지가 계속 표시됩니다.

TortoiseGit에게 감사드립니다!


답변

대화식 리베이스를 할 수 있습니다 git rebase -i . 매뉴얼 페이지에는 정확히 원하는 것이 있습니다.

http://git-scm.com/docs/git-rebase#_splitting_commits


이 글은 Git 카테고리에 분류되었고 태그가 있으며 님에 의해 에 작성되었습니다.