Git에서 루트 커밋을 편집 하시겠습니까?


328

나중에 커밋에서 메시지를 변경하는 방법이 있습니다.

git commit --amend                    # for the most recent commit
git rebase --interactive master~2     # but requires *parent*

부모가없는 첫 번째 커밋의 커밋 메시지를 어떻게 변경할 수 있습니까?



특히 다음과 같은 스크립트에서 GIT_COMMIT 환경 변수 사용git filter-branch --msg-filter
fork0

답변:


284

깨끗한 작업 트리가 있다고 가정하면 다음을 수행 할 수 있습니다.

# checkout the root commit
git checkout <sha1-of-root>

# amend the commit
git commit --amend

# rebase all the other commits in master onto the amended root
git rebase --onto HEAD HEAD master

23
나는 이것이되어야한다고 믿는다 git rebase --onto HEAD <sha1-of-root> master.
앤드류

5
맞습니다.하지만 <upstream> of에 대한 원래 루트 커밋을 원합니다 git rebase. <업스트림>에없는 git rebase<branch> ( master)에 커밋을 적용합니다 . HEAD에 있지 않으므로 master버전이 모두 적용하려고합니다 master.
앤드류

7
예, 그것의 확인 git rebase --onto HEAD <sha1-of-root>마스터 <sha1-of-root>에 사용 된 동일은 git checkout <sha1-of-root>. 그렇지 않으면 2를 갖습니다 first commit.
Andy

2
@ 컵케익 : 이전 버전의 명령을 테스트 했습니까? 잘 작동합니다. 수정은 커밋 메시지 만 변경하여 기존 루트 커밋과 새 루트 커밋에 정확히 동일한 변경 사항이 적용되므로 이전 루트 커밋은 자동으로 건너 뜁니다. 두 번째 HEAD는 모든 커밋을 고려하고 rebase의 두 매개 변수 버전을 사용하여 마스터로 다시 이동할 수 있도록합니다. 이 답변 --root은 리베이스 옵션 이 존재하기 전에 시작 됩니다.
CB Bailey

9
아래 의 ecdpalma의 답변 은 훨씬 쉽고 간단하며 더 많은 투표권을 가지고 있습니다.
Flimm

567

Git 버전 1.7.12 부터는 다음을 사용할 수 있습니다.

git rebase -i --root

선적 서류 비치


2
이 명령을 사용하여 모든 분기의 루트를 리베이스 할 수 있습니까? 현재 분기를 새로운 루트로 분리하고 다른 모든 분기는 기존 루트를 유지합니다
woojoo666

@ woojoo666 그러면 분기를 새로운 루트로 리베이스해야합니다. 평소와 같이.
berkus

@Atcold 업스트림 루트가 없으면 작동하지 않습니다.
Kai

경고 : 이것이 체크 아웃 된 브랜치의 루트를 잘못한다고 가정했지만 모든 커밋을로드 한 다음 모두 리베이스하는 데 시간이 걸립니다.
Leo

2
@ 레오 당신의 의견은 무엇을 의미합니까? 첫 번째 부분과 두 번째 부분 사이의 연결을 볼 수 없습니다. 시간이 오래 걸리는 것은 무엇입니까?
boycy

66

ecdpalma의 답변 을 확장하려면 이제 --root옵션을 사용 rebase하여 루트 / 첫 번째 커밋을 다시 쓰 겠다고 말할 수 있습니다.

git rebase --interactive --root

그러면 루트 커밋이 rebase TODO 목록에 표시되며이를 편집하거나 변경하도록 선택할 수 있습니다.

reword <root commit sha> <original message>
pick <other commit sha> <message>
...

이것은의 설명이다 --root에서 망할 놈 REBASE 워드 프로세서 (강조 광산) :

<branch>으로 제한하지 않고 에서 도달 가능한 모든 커밋을 리베이스하십시오 <upstream>. 이를 통해 브랜치에서 루트 커밋을 리베이스 할 수 있습니다 .


12

더 높은 등급의 답변에 대한 대안을 제공하기 위해 :

리포지토리를 만들면서 앞으로 "첫 번째"실제 커밋을 기반으로 할 것임을 미리 알고 있다면 처음에 명시 적으로 빈 커밋을 만들어이 문제를 피할 수 있습니다.

git commit --allow-empty -m "Initial commit"

그런 다음 "실제"커밋을 시작하십시오. 그런 다음 표준 방식으로 커밋을 쉽게 리베이스 할 수 있습니다.git rebase -i HEAD^


4
이것은 이것이 작동하기 위해서는 프로젝트가 시작될 때 빈 커밋을하기 위해 예지력 (또는 심령)이 필요하다는 것을 의미하지 않습니까? 이것은 나에게 매우 상황 이 좋으며 일반적으로 실용적이지 않은 것 같습니다 . 어떻게 생각해? 이미 100 개의 커밋을했는데 갑자기 루트 커밋을 편집해야하는 경우 어떻게됩니까? 이 경우 처음에 빈 커밋을하지 않으면 여전히 작동합니까?

2
루트 커밋의 메시지를 편집하는 것은 아마도 100을받은 후에하는 것이 아닙니다. 나는 때때로 git repo를 원하고, 쓸쓸한 커밋을하고, 일단 사용 가능한 상태에 도달하면 예를 들어 그것들을 하나로 스쿼시하고 메시지를 다시 말하겠다는 것을 알고 있습니다. 어쨌든, 이제 마음이 바뀌었고 첫 번째 커밋에 가장 유용한 것은 .gitattributes빈 커밋 대신 파일을 저장하는 것입니다.
jakub.g

4

당신은 사용할 수 있습니다 git filter-branch:

cd test
git init

touch initial
git add -A
git commit -m "Initial commit"

touch a
git add -A
git commit -m "a"

touch b
git add -A
git commit -m "b"

git log

-->
8e6b49e... b
945e92a... a
72fc158... Initial commit

git filter-branch --msg-filter \
"sed \"s|^Initial commit|New initial commit|g\"" -- --all

git log
-->
c5988ea... b
e0331fd... a
51995f1... New initial commit

필자는 필터 분기를 사용하여 작성자 / 커미터를 변경 -- --all하고이 옵션은 루트 커밋도 처리 할 수있는 핵심입니다.
sschuberth
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.