Magit으로 이전 커밋에 변경 사항 추가


42

나는 커밋 할 준비가 된 두 개의 커밋 (A와 B)을 가지고 있습니다. A에 무언가를 추가하는 것을 잊었다는 것을 알고 있습니다

Magit을 사용하여이 변경 사항을 A에 어떻게 추가 할 수 있습니까? 나는 Git 문서의 어느 부분을보아야하는지조차 모른다.

답변:


67

HEAD커밋 에 무언가를 추가하고자하는 순간을 예로 들어 보자. 예를 들어 "두 번째 커밋 B".

커밋 팝업 c에는 바인딩 " aAmend"이 있습니다. 해당 키를 누르면 HEAD커밋에 대한 단계별 변경 사항을 "수정"합니다 . 커밋은 Git에서 변경할 수 없으므로 실제로는 기존 커밋을 새로운 커밋으로 대체합니다. 이전 커밋 메시지가있는 버퍼가 팝업되어 추가 된 변경으로 인해 메시지를 조정해야하는 경우이를 수정할 수 있습니다. 항상 그렇듯이 C-c C-c메시지 편집이 끝나면를 누릅니다 . 이것은 git commit --amend명령 행 에서 실행 하는 것과 같습니다 .

  • a 수정 -단계적 변경 사항을 HEAD커밋 메시지에 추가 및 편집

변경 또는 메시지 만 조정하면되기 때문에 Magit은 두 가지 추가 변형을 제공합니다.

  • e 확장 - HEAD커밋 메시지를 편집하지 않고 단계적 변경 사항 추가
  • w Reword-HEAD 단계적 변경 사항을 추가하지 않고 메시지 변경

이 아닌 커밋을 편집 HEAD하려면 위의 작업이 작동하지 않습니다. 이 명령은 항상 HEAD커밋을 "수정"(즉, 교체)합니다 . Git은 커밋을 수정하기위한 단일 명령을 제공하지 않으므로 HEAD조금 더 복잡합니다.

Magit 그러한 명령을 제공하지만 여러 단계 로이 작업을 수행하는 것이 바람직한 상황이 있기 때문에 먼저 논의 할 것입니다.

커밋 수정 이외의 HEAD세 가지 단계로 나눌 수 있습니다.

  1. 다른 커밋 ( A)을 일시적으로 만듭니다 HEAD.
  2. HEAD(위에서 설명한대로)를 수정하여 commit을 생성하십시오 A'.
  3. 다음에 커밋을 다시 적용 힘내에게 A, 그러나 위에 A'.

대화식 리베이스를 사용하여 수행 할 수 있습니다. r리베이스 팝업을 표시하려면 입력 하십시오. 그런 다음 m"commit commit"rebase 변형을 호출하려면 입력 하십시오. 최근 커밋이있는 버퍼가 나타납니다. 수정하려는 커밋으로 이동하고 입력 C-c C-c하여 선택하십시오. Git은 해당 커밋으로 히스토리를 되 감고 진행중인 리베이스에 대한 정보를 상태 버퍼에 표시합니다.

HEAD위에서 설명한대로 수정하십시오 . 그런 다음 Git에게을 입력하여 완료되었다고 알려 r r주십시오. 경우 A'B충돌 후 REBASE에서 중지 B하고 충돌을 해결해야합니다. 완료했으면을 눌러 r r계속하십시오.

변경 사항이 A와 (과 B) 충돌이 있음을 알고 있으면 위에서 설명한대로 진행하고, 그렇지 않으면 다음 방법을 사용하십시오.


힘내을 사용하여 "수정 커밋"을 만들 수 있습니다 git commit --fixup A. 이것은 "다른 커밋에서 이루어져야 할"변경 사항을 기록 하는 새로운 커밋을 만듭니다 . 그 커밋은 새로운 것이됩니다 HEAD. --squash변형 도 있습니다 . 차이점에 대한 자세한 내용은 git-commit매뉴얼 페이지를 참조하십시오.

실제로 A커밋과 새 커밋을 결합한 A'다음 다시 적용 B하려면 rebase를 사용해야합니다. Magit은 편리한 명령을 제공합니다 r f.

위의 접근 방식과의 주요 차이점은 여기에서 먼저 새 커밋을 만든 다음 이를 "대상"과 결합하고 다시 적용하기 위해 리베이스합니다 B. 위에서 우리는 커밋하는 대신 rebasing으로 시작했습니다.

Magit에서 모두 --fixup--squash변형은에서 사용할 수 있습니다에 팝업을 커밋 f하고 s. 그러나 Magit은 또한 on F및 에 fixup 및 squash 명령의 "즉시"변형을 제공합니다 S. 이러한 변형은 "비 인스턴트"변형과 같은 새로운 커밋을 생성하지만 다른 명령을 호출하지 않고도 rebase를 사용하여 수정 커밋을 대상 커밋과 즉시 결합합니다.

"Instant fixup"( c F)은 "extend HEAD"( c e) 와 본질적으로 동일 HEAD합니다. 단, 확약뿐만 아니라 커밋에도 적용 됩니다.


더 읽을 거리 :


맑은! 멋진 패키지 BTW 감사합니다.
Mathieu Marques

1
글쎄, 나는 내 대답의 후반부에 약간의 부분이 있다고 생각합니다. 하지만 그을 피하기 위해 내가 ;-) 당신을 위해이 일을 기쁘게 생각하므로,이 이미 긴 대답의 길이를 두 배로해야 할 것입니다
안경 원숭이 속

이 답변 tarsius에 감사드립니다. 이것은 실제로 저에게 효과적입니다.
anquegi 2016 년

이 설명의 전반부의 명확성은 후반부를 읽는 것을 어렵게 만듭니다.
Lyn Headley

git-commit매뉴얼 페이지 리디렉션에 git-rebase(1)있는이 선이 : 제안 (가)의 커밋 메시지의 연결 커밋 접힌에 대한 커밋 메시지를 첫 번째 커밋하고 "스쿼시"명령을 가진 사람 만 생략합니다의은 "픽스 업"으로 커밋의 커밋 메시지 명령. IOW, 이전 커밋에서 코드를 수정 하려면 fixup을 사용 하고 커밋 메시지를 수정 하려면 squash 를 사용하십시오.
Yasushi Shoji

3

git commit --amend –C HEAD찾고자하는 Git 명령이며, Magit에서로 수정할 수 있습니다 C-c C-a.


Magit 최신 C-c C-a버전을 사용하고 있으며 이전 버전에서 온 것 같습니다. 또한 도움말 버퍼 ( ?) 에 "수정"이 표시되지 않습니다 .
Mathieu Marques

magit 2.x에 해당하는 Rémi의 답변 을 참조하십시오 .
npostavs

3

하나의 작업 흐름은 다음과 같습니다.

  • 당신의 변화를
  • c (커밋) f (수정-선택 커밋)

그때

  • r (리베이스) -a (자동 스쿼시, 기본값 설정 가능) i (대화식)

자동 스쿼시는 모든! fixup 커밋을 자동으로 올바른 위치로 옮기고 리베이스에서 스쿼시되도록 설정합니다.


내가 말하지 않은 유일한 것은 첫 번째 글 머리 기호와 두 번째 글 머리 기호 사이에있는 것입니다. 때리는 i것은 나를 산출합니다 Cannot rebase: Your index contains uncommitted changes. Please commit or stash them.. 커밋되지 않은 변경 사항이 없습니다. : /
Mathieu Marques

당기고 다시 시도했습니다 Proceed despite merge in rebase range? [c]ontinue, [s]elect other, [a]bort. 내 픽스 업이 다가오는 합병에 대해 똥을 낼 수 있다고 말하려고합니까?
Mathieu Marques

@MathieuMarques : "커밋되지 않은 변경 사항이없는 것을 제외하고"-자식은 당신이 생각합니다. 이 메시지는 준비되지 않은 변경이 아니라 단계별 변경을 제안합니다. 다시 : merge in rebase아래의 버그를 참조하십시오 git help rebase. 업스트림을 당기기 전에 수정 작업을 수행하는 것이 좋습니다.
npostavs

1

마지막 커밋을 수정하려면 "c a"입니다. Fixup은 이전 커밋을 수정하기위한 것입니다.


어떤 경우에, 나는 A 다음 B를 커밋했다 . 명확성을 위해 업데이트 된 게시물.
Mathieu Marques
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.