이미 분할 된 덩어리를 git으로 나눌 수 있습니까?


204

최근 patchadd명령 에 대한 git의 옵션을 발견 했으며 실제로 환상적인 기능이라고 말해야합니다. 또한 s키 를 쳐서 큰 덩어리를 작은 덩어리로 나눌 수 있다는 것을 발견했습니다 . 커밋의 정밀도가 높아집니다. 그러나 분할 덩어리가 충분히 작지 않으면 더 정밀하게하려면 어떻게해야합니까?

예를 들어, 이미 분할 된 덩어리를 고려하십시오.

@@ -34,12 +34,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

다음 커밋에만 CSS 주석 제거를 추가하려면 어떻게해야합니까? 이 s옵션은 더 이상 사용할 수 없습니다!

답변:


253

를 사용 git add -p하고로 분할 한 후에도 s약간의 변경이 없으면 e패치를 직접 편집하는 데 사용할 수 있습니다.

이것은 약간 혼란 스러울 수 있지만 편집기 창에서 주의 깊게 누르면 지시 사항 을 주의 깊게 따르면 e괜찮을 것입니다. 인용 한 경우 -다음 줄의 시작 부분에서 공백을 공백으로 바꿉니다.

-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {

... 다음 줄, 즉로 시작하는 줄을 삭제하십시오 +. 그런 다음 편집기를 저장하고 종료하면 CSS 주석 제거 만 준비됩니다.


9
멋진 솔루션! 나는 그것을 보았지만 오해했다 ... 나는 변화가 또한 작업 트리에서 제거 될 것이지만.
greg0ire 2016 년

7
실제로 도움말 텍스트에서 그다지 명확하지 않습니다. git이 각 커밋을 가능한 한 정확하고 아름답게 만들 것을 권장하기 때문에 실제로 이것을 많이 사용한다는 것을
알았습니다.

27
실제로 공백 으로 바꿔야합니다 . -문자를 삭제할 수 있다고 생각했는데 Git은 패치가 적용되지 않았다고 불평했습니다.
라이언 런디

3
줄을 '-'로 삭제하고 '+'를 공백으로 바꾸는 이유는 '-'가있는 줄이 이미 제거되고 '가있는 줄이 패치를 형성하기 때문입니다. +가 이미 추가되었습니다 (패치의 눈에). 또는 그것을 보는 또 다른 방법은 실제로 해당 문자 (-, +)가 나타내는 행을 추가하거나 제거하는 것입니다. '-'및 '+'가있는 나머지 행만 변경 사항으로 기록되고 나머지는 "파일의 상태"입니다.
톰톰

3
@Filype : 왜 그런 일이 일어 났는지 모르겠습니다. 두려운 git add -p덩어리를 실행 하고 편집 한 경우 e작업 트리가 아닌 단계적에만 영향을 미칩니다.
Mark Longair

60

당신의 example.css모습이 다음과 같다고 가정 해 봅시다 .

.classname {
  width: 440px;
}

/*#field_teacher_id {
  display: block;
} */

form.table-form #field_teacher + label,
form.table-form #field_producer_distributor + label {
  width: 300px;
}

.another {
  width: 420px;
}

이제 중간 블록에서 스타일 선택기를 변경해 보겠습니다. 이제 주석이 달린 스타일을 삭제하면 더 이상 필요하지 않습니다.

.classname {
  width: 440px;
}

#user-register form.table-form .field-type-checkbox label {
  width: 300px;
}

.another {
  width: 420px;
}

그것은 쉬웠다, 이제 커밋하자. 그러나 잠깐, 간단한 단계별 코드 검토를 위해 버전 제어 변경 사항을 논리적으로 분리하여 팀과 커밋 내역을 쉽게 검색 할 수 있도록하고 싶습니다.

기존 코드 삭제는 다른 스타일 선택기 변경과 논리적으로 분리되어 있습니다. 우리는 두 개의 별개의 커밋이 필요하므로 패치를 위해 덩어리를 추가합시다.

git add --patch
diff --git a/example.css b/example.css
index 426449d..50ecff9 100644
--- a/example.css
+++ b/example.css
@@ -2,12 +2,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

Stage this hunk [y,n,q,a,d,/,e,?]?

혹시, 변경 사항이 너무 가깝기 때문에 git이 변경했습니다.

스플릿이 정밀한 변경을 위해 충분히 세분화되지 않았기 때문에 프레스 를 통해 스플릿을 시도해도 s동일한 결과를 얻습니다.git이 패치를 자동으로 분할하려면 변경된 줄 사이에 변경되지 않은 줄이 필요 합니다.

을 눌러 수동으로 편집 하겠습니다e

Stage this hunk [y,n,q,a,d,/,e,?]? e

git은 선택한 편집기에서 패치를 엽니 다.

# Manual hunk edit mode -- see bottom for a quick guide
@@ -2,12 +2,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */
-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging. If it does not apply cleanly, you will be given
# an opportunity to edit again. If all lines of the hunk are removed,
# then the edit is aborted and the hunk is left unchanged.

목표를 검토해 봅시다 :

다음 커밋에만 CSS 주석 제거를 추가하려면 어떻게해야합니까?

이것을 두 개의 커밋으로 나누고 싶습니다.

  1. 첫 번째 커밋은 일부 줄을 삭제합니다 (코멘트 제거).

    주석 처리 된 행을 제거하려면 해당 행을 그대로 두십시오. 원하는대로 버전 제어에서 삭제를 추적하도록 이미 표시되어 있습니다.

    -/*#field_teacher_id {
    - display: block;
    -} */

  2. 두 번째 커밋은 변경 사항이며, 삭제와 추가 사항을 모두 기록하여 추적됩니다.

    • 삭제 (이전 선택기 행 제거)

      이전 선택기 행을 유지하려면 (이 커밋 중에 삭제하지 마십시오) ...

      '-'줄을 제거하려면 ''를 만드십시오.

      문자 그대로 빼기 -기호 를 공백 문자로 바꾸는 것을 의미 합니다.

      이 세 줄은 ...

      -
      -form.table-form #field_teacher + label,
      -form.table-form #field_producer_distributor + label {

      ...이 될 것이다 ( 통지 3 개 라인의 처음에 하나의 공간) :


      form.table-form #field_teacher + label,
      form.table-form #field_producer_distributor + label {

    • 추가 (새로운 선택기 라인 추가)

      이 커밋 중에 추가 된 새로운 선택기 라인에주의를 기울이지 않기 위해 ...

      '+'줄을 제거하려면 삭제하십시오.

      문자 그대로 전체 줄을 삭제하는 것을 의미합니다.

      +#user-register form.table-form .field-type-checkbox label {

      (Bonus : vim 을 편집기로 사용하는 경우을 눌러 dd줄을 삭제합니다. Nano 사용자는 Ctrl+을 누름 K)

저장할 때 편집기는 다음과 같아야합니다.

# Manual hunk edit mode -- see bottom for a quick guide
@@ -2,12 +2,7 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */

 form.table-form #field_teacher + label,
 form.table-form #field_producer_distributor + label {
   width: 300px;
 }

# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging. If it does not apply cleanly, you will be given
# an opportunity to edit again. If all lines of the hunk are removed,
# then the edit is aborted and the hunk is left unchanged.

이제 커밋합시다.

git commit -m "remove old code"

그리고 마지막 커밋의 변경 사항을 확인하십시오.

git show
commit 572ecbc7beecca495c8965ce54fbccabdd085112
Author: Jeff Puckett <jeff@jeffpuckett.com>
Date:   Sat Jun 11 17:06:48 2016 -0500

    remove old code

diff --git a/example.css b/example.css
index 426449d..d04c832 100644
--- a/example.css
+++ b/example.css
@@ -2,9 +2,6 @@
   width: 440px;
 }

-/*#field_teacher_id {
-  display: block;
-} */

 form.table-form #field_teacher + label,
 form.table-form #field_producer_distributor + label {

완벽-삭제 만 해당 원자 커밋에 포함되어 있음을 알 수 있습니다. 이제 작업을 마치고 나머지는 커밋하십시오.

git add .
git commit -m "change selectors"
git show
commit 83ec3c16b73bca799e4ed525148cf303e0bd39f9
Author: Jeff Puckett <jeff@jeffpuckett.com>
Date:   Sat Jun 11 17:09:12 2016 -0500

    change selectors

diff --git a/example.css b/example.css
index d04c832..50ecff9 100644
--- a/example.css
+++ b/example.css
@@ -2,9 +2,7 @@
   width: 440px;
 }

-
-form.table-form #field_teacher + label,
-form.table-form #field_producer_distributor + label {
+#user-register form.table-form .field-type-checkbox label {
   width: 300px;
 }

마지막으로 마지막 커밋에 선택기 변경 사항 만 포함되어 있음을 알 수 있습니다.


1
보너스 # 2 : VIM을 편집기로 사용하는 경우 줄을 삭제하려면 키보드에서 "d"를 두 번 눌러야합니다. : D
Alexxus

3
또한, 대신에 추가하지 않을 추가 라인을 제거, 당신은 대체 할 수 +와 함께 #. 결과는 동일하지만 삭제하거나 되돌릴 수없는 불편하거나 저장하기 전에 실험하고 싶을 수 있습니다.
ob-ivan

그리고 vim은 r #플러스 xD 이상입니다
aksh1618

목표는 "다음 커밋에만 CSS 주석 제거를 추가하는 방법은 무엇입니까?"입니다. 그러나 단계는 실제로 달성 한 내용에 대해 혼란 스럽습니다. (우리는 다음 커밋에 몇 줄의 "제거"만 "추가"하고 싶습니다.) 단순히 remove 또는 add를 말하는 것은 매우 혼란 스럽습니다. 각 단계에서 달성 한 내용을 명시하면 명확하게 설명 할 수 있습니다.
ahnbizcad

9

git gui를 사용할 수 있으면 변경 사항을 한 줄씩 단계별로 지정할 수 있습니다. 불행히도, 나는 명령 줄에서 또는 가능하다면 어떻게 해야하는지 모른다.

과거에 사용했던 또 다른 옵션은 변경 부분을 롤백하고 (편집기를 열어 둔 상태로 유지) 원하는 비트를 커밋하고 실행 취소 한 후 편집기에서 다시 저장하는 것입니다. 매우 우아하지는 않지만 작업을 완료합니다. :)


편집 (git-gui 사용법) :

git-gui가 msysgit 및 Linux 버전에서 동일한 지 확실하지 않지만 msysgit 하나만 사용했습니다. 그러나 동일하다고 가정하면 실행하면 네 개의 창이 있습니다. 왼쪽 상단 창은 작업 디렉토리 변경 사항이며, 왼쪽 하단은 단계 변경 사항입니다. 오른쪽 상단은 선택한 파일의 diff입니다 (디렉토리가 작동하는지 여부) 또는 단계적), 오른쪽 아래는 커밋에 대한 설명입니다 (필요하지 않을 것 같습니다). 오른쪽 상단의 파일을 클릭하면 차이점이 나타납니다. diff 행을 마우스 오른쪽 버튼으로 클릭하면 상황에 맞는 메뉴가 표시됩니다. 주목해야 할 두 가지 옵션은 "커밋을위한 스테이지 행크"및 "커밋을위한 스테이지 라인"입니다. 커밋하려는 줄에서 "커밋을위한 준비 단계"를 계속 선택하면 완료됩니다. 원하는 경우 여러 줄을 선택하여 스테이징 할 수도 있습니다.

커밋하는 경우 gui 도구 또는 명령 줄을 사용할 수 있습니다.


두 번째 제안은 분명하지만 첫 번째 제안은 흥미 롭습니다. 좀 더 자세히 설명해 주시겠습니까? 나는 설치 git-gui했지만 당신이 묘사 한 것을 성취하는 방법에 대한 단서가 없습니다.
greg0ire

탱크를 많이! 작동합니다! 클릭 한 번으로 스테이지를 만들고 색인을 생성 할 줄을 선택할 수도있었습니다.
greg0ire

0

이를 수행하는 한 가지 방법은 git add필요한 다른 청크를 건너 뛰고 실행하는 것입니다.git add 다시 것입니다. 이것이 유일한 덩어리 인 경우 분할 할 수 있습니다.

커밋 순서가 걱정되면을 사용하십시오 git rebase -i.


이것은 내가 시도한 것이며 내 질문에있는 덩어리는 git add -p다시 실행할 때 유일한 것이지만 그것을 나눌 수는 없습니다. 나는 이것을 얻는다 : Stage this hunk [y,n,q,a,d,/,e,?]?그리고 나서 's'를 치면 도움이된다. BTW, 당신은 add patch아니지 patch add? 아니면 git patch설치해야 할 플러그인이 있습니까?
greg0ire

이것을 다시 실행하기 전에 준비된 덩어리를 커밋 했습니까? 그리고 머큐리얼에는 플러그인이 있지만 Git에는 없습니다.
Abizern

아니요, 나는 그들이 같은 커밋에 있기를 원합니다 (그러나 솔루션이 작동하면 --amend을 사용하여 이것을 달성 할 수 있다고 생각합니다). 시도해 볼게요.
greg0ire

내 대답이 말했듯이 → git rebase -i. 보다 유연한commit --amend
Abizern
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.