커밋 순서 변경


104

현재 브랜치에서 작업 중이며 일부 커밋을 다른 브랜치에 병합하고 싶습니다.

    a-b-c-d-e-f-g (branchA)
   /
--o-x-x-x-x-x-x-x-x-x-x (master)
   \
    x-x-x-x-x (branchB)

(문자는 커밋을 나타내며 "x"는 관련없는 커밋입니다.)

그러나 일부 커밋을 풀링하는 것이 좋은 생각이라는 것을 알았습니다. 커밋 a, d, e 및 g를 하나의 패치로 "연결"하고 마스터에 커밋하고 싶습니다. 커밋 b와 f는 branchB에 대한 하나의 커밋으로 이동해야합니다. 그것을 달성하는 좋은 'git'-ish 방법이 있습니까?


4
이미 주어진 두 가지 답변에는 올바른 명령이 언급되어 있지만이 작업과 같이 기본적인 작업으로 여기 StackOverflow에서 실제 지침을 갖는 것이 가치가 있다고 생각하므로 몇 가지를 게시했습니다. (링크 할 좋은 이전 질문을 찾을 수 없다는 것이 놀랍습니다.)
Cascabel

답변:


125

찾고있는 명령은 git rebase특히 -i/--interactive옵션입니다.

나는 당신이 브랜치 A에 커밋 c를 남기고 싶다고 가정하고 병합이 간단하기 때문에 다른 커밋을 병합하는 대신 다른 브랜치로 옮기고 싶다는 의미입니다. 분기 A를 조작하여 시작하겠습니다.

git rebase -i <SHA1 of commit a>^ branchA

^이전 커밋 수단이 때문에,이 명령은 "A"로 기본 전에 커밋 사용하여 지점 A를 리베이스 말한다. Git은이 범위의 커밋 목록을 제공합니다. 순서를 바꾸고 git에게 적절한 항목을 스쿼시하도록 지시하십시오.

pick c ...
pick a ...
squash d ...
squash e ...
squash g ...
pick b
squash f

이제 히스토리는 다음과 같아야합니다.

    c - [a+d+e+g] - [b+f] (branchA)
   /
--o-x-x-x-x-x-x-x-x-x-x (master)

이제 branchB에 대해 새로 스 쿼싱 된 커밋 b + f를 가져옵니다.

git checkout branchB
git cherry-pick branchA  # cherry-pick one commit, the tip of branchA

마스터의 경우 a + d + e + g에 대해서도 동일합니다.

git checkout master
git cherry-pick branchA^

마지막으로 branchA를 업데이트하여 c를 가리 킵니다.

git branch -f branchA branchA^^

이제 다음이 필요합니다.

    c (branch A) - [a+d+e+g] - [b+f] (dangling commits)
   /
--o-x-x-x-x-x-x-x-x-x-x-[a+d+e+g] (master)
   \
    x-x-x-x-x-[b+f] (branchB)

분기간에 이동하려는 커밋이 여러 개있는 경우 rebase를 다시 사용할 수 있습니다 (비대화 형).

# create a temporary branch
git branch fromAtoB branchA
# move branchA back two commits
git branch -f branchA branchA~2
# rebase those two commits onto branchB
git rebase --onto branchB branchA fromAtoB
# merge (fast-forward) these into branchB
git checkout branchB
git merge fromAtoB
# clean up
git branch -d fromAtoB

마지막으로 면책 조항 : 일부가 더 이상 깔끔하게 적용되지 않는 방식으로 커밋을 재정렬하는 것이 가능합니다. 이것은 잘못된 순서를 선택했기 때문일 수 있습니다 (패치 된 기능을 소개하는 커밋 전에 패치를 배치). 이 경우 rebase ( git rebase --abort) 를 중단 할 수 있습니다. 그렇지 않으면 (병합 충돌과 마찬가지로) 지능적으로 충돌을 수정하고 수정 사항을 추가 한 다음 실행 git rebase --continue하여 계속 진행해야합니다. 이러한 지침은 충돌이 발생할 때 인쇄되는 오류 메시지에서도 제공됩니다.


git branch -f branchA branchA^^틀린 뒤 다이어그램이 아닌가요? 즉, 도면의 첫번째 행이되도록, 이때 C를 가리키는 될 branchA 안 c (branchA)하지 c - [a+d+e+g] - [b+f] (branchA)?
ntc2

@enoksrd : 예, 실수가 있지만 편집에 실수가 있습니다. 여기서 기회가 생기면 고칠 게요.
Cascabel 2012-06-05

대신 A 지점에서 git branch -f branchA branchA^^할 수없는 이유는 git reset --hard <sha1 of c>무엇입니까?
Mikhail Vasilyev

17
git rebase -i HEAD~3

3재정렬이 필요한 커밋 수는 어디에 있습니까 ( source ).

이것은 vi 를 열고 가장 오래된 (위)에서 최신 (아래)으로 커밋을 나열 합니다.
이제 다시 정렬 라인, 저장종료 편집기를.

ddp현재 행을 아래
ddkP 로 이동합니다. 현재 행을 위로 이동 합니다 ( 소스 ).


9

git rebase --interactive 원하는 명령입니다.

예:

현재 상태는 다음과 같습니다.

bernt@le3180:~/src/stackoverflow/reordering_of_commits
$ git status
On branch master
nothing to commit, working tree clean
bernt@le3180:~/src/stackoverflow/reordering_of_commits
$ git log --oneline
a6e3c6a (HEAD -> master) Fourth commit
9a24b81 Third commit
7bdfb68 Second commit
186d1e0 First commit

커밋 9a24b81(세 번째 커밋)과 7bdfb68(두 번째 커밋) 순서를 바꾸고 싶습니다 . 이렇게하려면 먼저 변경하려는 첫 번째 커밋 전에 커밋을 찾습니다 . 이것은 커밋 186d1e0(첫 번째 커밋)입니다.

실행할 명령은 git rebase --interactive COMMIT-BEFORE-FIRST-COMMIT-WE-WANT-TO-CHANGE입니다.이 경우 :

bernt@le3180:~/src/stackoverflow/reordering_of_commits
$ git rebase --interactive 186d1e0

그러면 다음 내용이 포함 된 파일이 기본 편집기에서 열립니다.

pick 7bdfb68 Second commit
pick 9a24b81 Third commit
pick a6e3c6a Fourth commit

# Rebase 186d1e0..a6e3c6a onto 186d1e0 (3 commands)
#
# 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
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#

파일의 커밋 순서는 git log에 사용되는 순서와 반대입니다. git log에서 가장 최근 커밋은 맨 위에 있습니다. 이 파일에서 가장 최근 커밋은 맨 아래에 있습니다.

파일 하단의 주석에서 설명하는 것처럼 커밋을 스쿼시, 삭제 및 재정렬하는 등 제가 할 수있는 다양한 작업이 있습니다. 커밋 순서를 변경하려면 다음과 같이 파일을 편집합니다 (하단 주석은 표시되지 않음).

pick 9a24b81 Third commit
pick 7bdfb68 Second commit
pick a6e3c6a Fourth commit

pick각 라인 수단 "사용 (예 포함)이 커밋"내가하고 REBASE 명령과 임시 파일 저장 편집기를 종료 할 때, 자식이 명령을 실행하고 저장소와 작업 디렉토리를 업데이트의 시작 명령

$ git rebase --interactive 186d1e0
Successfully rebased and updated refs/heads/master.
bernt@le3180:~/src/stackoverflow/reordering_of_commits
$ git log --oneline
ba48fc9 (HEAD -> master) Fourth commit
119639c Second commit
9716581 Third commit
186d1e0 First commit

재 작성된 커밋 기록을 확인합니다.

연결:


1
완전하고 독립적 인 답변을 제공하려면 링크에서 관련 세부 정보를 추가하세요. 그래서 "링크 전용 답변"에 눈살을 찌푸립니다. 구체적으로, git rebase --interactiveOP의 목표를 달성하기 위해 어떻게 사용 합니까?
SherylHohman

두 번째 링크는 현재 존재하지 않습니다.
devsaw

답변을 완전하고 독립적으로 만들기 위해 콘텐츠를 추가했습니다. 두 번째 링크를 제거했습니다.
codeape 2019-04-30


-1

git rebase 는 당신이 원하는 것입니다. --interactive 옵션을 확인하십시오.


4
완전하고 독립적 인 답변을 제공하려면 링크에서 관련 세부 정보를 추가하세요. 그래서 "링크 전용 답변"에 눈살을 찌푸립니다.
SherylHohman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.