진행중인 리팩토링을 수행하는 방법은 무엇입니까?


23

그래서 나는이 큰 프로젝트를 가지고 있는데, 그것은 나에 의해 리팩토링되는 과정에 있습니다. 나는 많은 것들을 바꾸고 있기 때문에 곧 컴파일 할 수있는 기회가 없습니다. 나는 이름이 붙은 특별한 자식 지점에 살고 있습니다 cleanup( master물론 결국 합쳐질 것 입니다).

문제는 나 / 우리는 비 컴파일 코드를 커밋하지 않는 정책을 가지고 있다는 것입니다. 따라서이 거대한 작업을 마치기 전까지는 (검토 또는 부기) 어떤 것도 커밋 할 수 없습니다.
이것은 내가 일하는 방식이 아닙니다 (대부분의 사람들은 적어도 하루에 한 번 정도 노력합니다).

어떻게 생각해? 내가 간과하는 해결책이 있습니까?
나중에 git에게 커밋 또는 무언가를 집계하도록 지시 할 수 있습니까? 나는 비 컴파일만큼 그들은으로 커밋 살 수 있을cleanup지점입니다.

편집하다

푸시 / 커밋의 주제 : 나는 그것이 큰 차이라는 것을 알고 있지만 나중에 물건을에 병합 할 때 개정이 깨질 것 master입니다. 따라서 역사를 살펴보면 (또는 git bisect...) "로컬"개정판을 세계적으로 액세스 할 수 있습니다. 따라서 로컬로 커밋하고 푸시하지 않는 것이 나중에 해결하는 데 문제가 발생할 수 있으므로 최선의 해결책은 아닙니다.

한마디로 : 로컬 커밋은 결국 푸시됩니다. 글로벌 히스토리에는 비 컴파일 커밋이 표시되지 않아야합니다.


1
단일 글로벌 커밋에서 여러 로컬 커밋을 수집 할 수 있습니다.

@ Thorbjørn은 아래의 Jim의 권장 사항입니까, 아니면 Git 내의 다른 메커니즘입니까?
Brian

나는 믿습니다-정확한 명령을 기억할 수 없습니다.

5
리팩토링하지 않고 더 큰 일을하고 있습니다. 코드베이스에서 각각의 리팩터링 후에는 코드가 컴파일되고 똑같은 관찰 가능한 동작을 가져야합니다. 내 즉각적인 반응이 "언제나 당신이 가진 것을 커밋하면 모든 것이 잘 작동한다"는 것을 반영하기 위해 질문 제목을 변경하고 싶을 수도 있습니다.
David Thornley

1
@bitmask 다시 쓰기는 어떻습니까?
Dave Hillier

답변:


21

git merge --squash명령을 사용하면 다른 분기를 병합하는 것과 동일한 효과를 갖는 현재 분기 위에 단일 커밋을 만들 수 있습니다. 이 명령은 작업 트리를 업데이트하고 색인에서 변경 사항을 스테이징하므로 다음에 수행해야 할 것은 commit입니다.

git checkout master
git merge --squash cleanup
git commit -m "Merge cleanup branch"

git rebase -i명령은 커밋을 스쿼시 할 수도 있지만 더 많은 작업이 필요합니다.


14

다시 쓰기는 리팩토링이 아닙니다

Git 사용 방법에 관심이 있다는 것을 알고 있지만 Git을 사용하는 방식보다 리팩토링 방식을 변경하는 것이 좋습니다 (Git이 도움을 줄 수 있다고 생각하지만)

Martin Fowler는 리팩토링을 다음 과 같이 정의합니다 .

기존 코드 본문을 재구성하여 외부 동작을 변경하지 않고 내부 구조를 변경하는 훈련 된 기술.

그 핵심은 변화를 보존하는 일련의 작은 행동입니다. 각 변환 ( "리팩토링"이라고 함)은 거의 수행하지 않지만 일련의 변환은 상당한 구조 조정을 생성 할 수 있습니다. 각 리팩토링은 작기 때문에 잘못 될 가능성이 적습니다. 작은 리팩터링 후에도 시스템이 완전히 작동하므로 재구성 중에 시스템이 심각하게 손상 될 가능성이 줄어 듭니다.

이 방법을 적용하면 정기적으로 커밋 (및 푸시) 할 수 있습니다.

이것이 비현실적이며 대규모로는 작동하지 않는다고 주장 할 수 있습니다. 이것은 Mikado 방법 이 도움이 될 수 있는 곳 입니다. 종속성 그래프를 작성하여 큰 리팩토링을 일련의 작은 리팩토링으로 분해합니다. 이 방법은 재귀 적입니다. 변경을 시도하십시오. 체크인 할 때 문제가 발생하지 않습니다. 그렇지 않으면 변경 사항을 되돌리고 전제 조건을 기록하십시오. 주요 리팩토링 목표를 달성 할 수있을 때까지 이러한 사전 요구 사항 리팩토링을 하나씩 수정합니다.

힘내 정말이 방법을 도울 수 있습니다. 지역 (파산) 지점을 유지할 수 있습니다. 하위 목표를 커밋 (및 푸시) 할 rebase때 더 이상 중단되지 않을 때까지 방금 수행 한 커밋 위에 기본 목표 분기를 지정할 수 있습니다.


5

매뉴얼 페이지 git rebase에서 특히 git rebase -i변형 을 확인하십시오 . 그것은 당신이 당신이 찾고있는 것처럼 들리는 히스토리에서 커밋의 수를 재주문, 삭제 또는 스쿼시 할 수있게합니다. 나는 당신이 묘사 한 상황에서 항상 그것을 사용합니다 : 공공 소비에 적합하지 않은 많은 작은 커밋을 만든 다음 공유 리포지토리로 푸시하기 전에 단일 "리팩토링"커밋으로 스쿼시합니다.


3

당신은 따라서, 힘내를 사용하는 커밋 반드시 의미하는 것은 아니다 밀어 .... 변경

IMHO 및 Git과 함께 작업하면 컴파일하지 않아도 작업을 커밋하는 것이 좋습니다. 결국 일단 변경 사항을 커밋하면 아무도 코드를 사용할 수 없기 때문에 (누를 때까지) 사용할 수 없습니다. 물론이를 푸시하기 전에 다른 사용자가 문제없이 변경 사항을 가져 와서 병합 할 수 있도록 제대로 작동하고 컴파일해야합니다.

또한 마스터 브랜치와 다른 브랜치에서 작업하고 있습니다. 따라서 원하는 경우 (이를 권장합니다) 지점을 밀지 않습니다. 리팩토링을 마치면 마스터 브랜치를 체크 아웃하고 변경 사항을 병합하고 마스터 브랜치를 푸시하면됩니다.

편집하다

이 경우 당신은 함께 사용 git cherry-pick하거나 놀 수 있습니다git rebase


중요한 메모이지만 이것을 고려했습니다. 내 편집 내용을 참조하십시오. 고맙습니다.
비트 마스크

위의 편집 내용을 참조하십시오.
Cristian

내가 할 수 있다면 나는 -1 일 것이다. 커밋이 가능해집니다! 지역에서 진행중인 커밋은 훌륭하지만 결코 밀어 붙이지 않습니다. 그것은 코드를 이해하기 어렵게 만들고, git bisect를 방해하고, 역사를 복잡하게 만듭니다. 대신 리베이스 또는 스쿼시.
RJFalconer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.