포맷 및 버전 관리


23

코드 형식이 중요합니다. 심지어 들여 쓰기 문제 . 그리고 약간의 개선보다 일관성이 중요합니다. 그러나 프로젝트는 일반적으로 1 일부터 명확하고, 완전하며, 검증 가능 하고 시행되는 스타일 가이드 가 없으며 , 주요 개선 사항은 언제든지 도착할 수 있습니다. 어쩌면 당신은 그것을 발견

SELECT id, name, address
FROM persons JOIN addresses ON persons.id = addresses.person_id;

/보다 나은 것으로 쓰여질 수있다

SELECT persons.id,
       persons.name,
       addresses.address
  FROM persons
  JOIN addresses ON persons.id = addresses.person_id;

쿼리에 더 많은 열을 추가하는 동안 어쩌면 이것은 코드에서 네 가지 쿼리 중 가장 복잡하거나 수천 개 중 사소한 쿼리 일 수 있습니다. 전환이 아무리 어려워도 가치가 있다고 결정합니다. 그러나 주요 서식 변경에서 코드 변경을 어떻게 추적합니까? 포기하고 "이 시점에서 다시 시작합니다"라고 말하거나 전체 리포지토리 기록에서 모든 쿼리를 다시 포맷 할 수 있습니다.

Git과 같은 분산 버전 제어 시스템을 사용하는 경우 첫 번째 커밋으로 되돌리고 현재 상태로 다시 포맷 할 수 있습니다. 그러나 그것은 많은 일이며, 다른 모든 사람들은 일이 진행되는 동안 일을 멈추거나 모든 합병의 어머니를 위해 준비해야합니다. 모든 결과를 최대한 활용하는 기록을 변경하는 더 좋은 방법이 있습니까?

  • 모든 커밋에서 동일한 스타일
  • 최소한의 병합 작업

?

명확히하기 위해, 이것은 프로젝트를 시작할 때 모범 사례가 아니라 대규모 리팩토링이 Good Thing ™으로 간주되었지만 여전히 추적 가능한 이력을 원할 때 수행해야하는 조치에 관한 것입니다. 버전이 항상 동일하게 작동하도록하는 유일한 방법 인 경우 기록을 다시 쓰지 않는 것이 좋습니다. 그러나 새로 다시 작성하면 개발자의 이점은 무엇입니까? 특히 재 작성된 버전이 원본과 정확히 동일한 방식으로 작동하도록하는 방법 (테스트, 구문 정의 또는 컴파일 후 동일한 바이너리)이있는 경우?


24
왜 역사를 다시 쓰고 싶습니까? 버전 관리의 목적을 상실합니다. 3 개월 전에 제공 한 응용 프로그램이 약간의 의심없이 개정 xxxxxx와 일치하는지 확인하려고합니다. 사소한 재 포맷조차도 용납 할 수 없습니다.
Simon Bergot 2016 년

5
코멘트 커밋에 같은 I I는 "재 포맷 기능적인 변화."태그로이 작업을 수행 할 것을
조작

3
관련이없는 주제에 대해서는 모든 코드를 다시 포맷하여 Git 기록을 다시 작성하도록 제안하는 것처럼 들립니다. 사람들에게 아이디어를 제공하지 마십시오. Git 기록을 다시 작성하는 것은 사례의 99.9 %에 좋지 않습니다. 재 포맷은 0.1 % 엣지 케이스가 아닙니다.
Andrew T Finnell 2016 년

4
일부 언어 (Python을보고 있음)에서 재 포맷하면 코드의 논리적 기능이 변경 될 수 있습니다. 재 포맷을 안전하게 추적하고 무시하려면 VCS에 저장된 모든 언어를 구문 분석 할 수 있어야합니다.
Joris Timmermans 2016 년

3
재 포맷은 코드 변경이므로 그렇게 커밋해야합니다.
David Cowden 2016 년

답변:


26

개별 커밋으로 재 포맷을 수행하십시오. 이것은 역사를 최소한으로 방해 할 것이며, 어떤 커밋이 재 포맷되고 실제로 코드가 변경되는지 한눈에 볼 수 있어야합니다. 비뚤어 git blame지고 비슷할 수 있지만 재 포맷 전용 커밋을 가리키는 경우 이전 변경 사항을 찾는 것이 매우 간단합니다.


개발자 중 한 사람이 이것이 좋은 생각이라고 생각했기 때문에 몇 주 동안 프로젝트가 탈선 된 것을 보았습니다 . 이 작업을 수행하려면 사전에 위험을 이해하고 서식 지정을 얼마나 멀리 진행할지 결정하십시오. 나는 mjfgates가 정답이라고 생각합니다.
Johntron

1
문제의 팀이 코드 형식보다 문제가 더 큰 것 같습니다. 그러나 네, 당신이해야 할 일이 아니라면 이것을하지 않는 것이 좋습니다. 경우 변경 내용을 다시 포맷하고 싶은, 난 여전히 더 나은 말하는 기능의 변화와 혼합보다는 별도의 커밋로 할 것입니다.
harald

예, 많은 문제가 있습니다 .PI는 새로운 개발자에게 들리는 것처럼 단순하지 않다고 경고하고 싶어합니다. 대량 재 포맷 도구는 위험합니다 (특히 정규식을 사용하여 직접 빌드하는 경우-적어도 AST 사용). 개인적으로, 각 파일의 스타일과 일치하도록 코드를 작성하지만 몇 가지 함수가 다시 포맷 될 때 코드를 검토하는 것은 중요하지 않습니다. 많은 개발자들이 코드 스타일에 매달리고 아키텍처, 프로세스, 툴링 등과 같은 더 큰 문제를 무시합니다.
Johntron

프로그래밍에서 들리는 것만 큼 간단
하지는 않습니다

13

VCS 기록을 다시 쓰지 마십시오 . VCS 원칙에 위배됩니다.

서식 수정을 자동화하려고 시도하지 마십시오 . 실제 문제가 아니라 증상을 치료하고 있습니다 (= 코딩 표준을 따르지 않는 개발자).

공통 문서에서 코딩 표준 및 서식 모범 사례를 정의하고 모든 개발자의 동의를 얻습니다.

Git은 분산되어 있기 때문에 훌륭합니다. DVCS를 사용하면 게이트 키퍼 워크 플로우를 통해 모범 사례를 시행하기가 매우 쉽습니다 . 게이트 키퍼 는 공통 지침을 따르지 않는 병합 제안 (= Git의 풀 요청)을 거부 합니다. 그리고 나는 굵은 글씨로 거부를 , 그렇지 않으면 위반하는 코더는 규칙을 따르지 않고 동일한 실수를 계속 반복하지 않을 것입니다.

이 기술은 저에게 효과적입니다. 코더는 자신의 작업이 병합되기를 원하므로 처음 몇 번의 실수 후에 규칙을 따르기 시작합니다.

기존 코드베이스를 수정하는 경우 ... 모듈별로 또는 프로젝트에 적합하게 점진적으로 수행하는 것이 좋습니다. 각 단계에서 신중하게 테스트하십시오. 어리석게 들릴 수도 있지만 서식과 같은 사소한 변경으로도 실수가 발생하므로 약간의 충돌이 발생할 수 있습니다.


1
저자는 이것이 "... 첫날부터 명확하고, 완전하며, 검증 가능하고 시행 된 스타일 가이드"로 시작하지 않은 프로젝트와 관련하여 명확하게 언급하고 있기 때문에 공감되었습니다. 그는 이미 일어난 실제 문제를 처리 할 수 ​​없습니다. 나는 당신에게 동의합니다 :)
Johntron

2
거부 는 인간과 로봇 사이에 싸움이있을 것임을 의미합니다. 거기에 있었다. 조만간 로봇은 읽을 수없는 방식으로 형식을 지정하려면 실제로 복잡한 코드가 필요합니다. 예 : Java 문자열은 실제로 SQL 문이지만 로봇은이를 알지 못합니다. Parens를 닫기 전의 공백은 로봇을위한 것이 아니라 사람을위한 코드의 구조에 관한 정보를 전달할 수 있습니다. 함수 매개 변수는 가장 의미가없는 방식으로 여러 줄로 분할됩니다.
18446744073709551615

9

실제 질문에 대한 대답은 "그렇지 않습니다"입니다. 나는 한 가지 방법으로 포맷 된 코드에서 주요 포맷 변경을 통해 코드가 새로운 방식으로 포맷 된 후 추가 변경을 통해 로직의 변경 사항을 추적 할 수있는 현재 SCM 도구가 없습니다. 그리고 당신은 이것을 알고 있습니다. 코드 조각에서 역사를 잃어 버리는 것은 좋지 않습니다.

따라서 첫 문장과 모순됩니다. 코드 문제가되지 않습니다 서식 많이 있습니다. 꽤 좋지만, 우리가 여기있는 것은 아닙니다. 나는 2 공간 들여 쓰기로 누군가의 오래된 지옥 같은 이상한 K & R 변형 코드에 버려지는 사람을 이해하지만 (1) ... ... 서식이 예외적 인 것이 아니라면 실제로 진행 상황을 이해하는 데 방해가되지 않습니다 병리학. 이 경우 어쨌든 코드를 변경하는 데 문제가 발생하므로 방해하지 않아야합니다.

따라서 기존 코드를 엄격하게 변경하여 다시 포맷하는 것은 가치가 없습니다. 변수 이름을 바꾸고, 긴 함수를 나누고, 내용을 바꾸는 좋은 리팩토링 요소는 물론 재 포맷은 아닙니다.

1)-한때 Windows 클립 보드 뷰어를 소유 한 적이 있습니다. 모든 것은 하나의 150k C 모듈이었습니다. 다른 사람들이 서로 30 줄 안에 5 개의 다른 버팀대 스타일을 사용했던 지점을 찾았습니다. 그러나 일의 그 부분은 효과가 있었다. 나는 10 년 동안 그 코드 덩어리를 인쇄했지만, 역사가 중요하기 때문에 그것을 찌르지 않았으며 그 코드는 적어도 3 개의 소스 트리 (Windows 3.x, NT, 미래 95)에 있었으며 모두 살았습니다. 다른 건물에서.


과거에는을 사용하여 hg파트 별 병합이 까다로운 큰 리 팩터 병합 에 대처하는 데 유용한 도구라는 것을 알았습니다 . 일반적으로 큰 리 팩터 앞에 커밋을 병합 한 다음 큰 리 팩터 자체를 병합 한 다음 리 팩터 이후 커밋을 병합합니다. 이 세 가지 병합 각각 그 자체가 되어 많은 후 수습에 혼란을 시도하고 쉽게 그 한 가지에 병합 모든 일의 결과.
Mark Booth

나는 완전히 동의한다! 또한, 많은 개발자들이 형식 재 지정 및 코드 스타일에 대해 선구자 적이라고 생각합니다. 여기에 쉼표 / ​​세미콜론이 없으면 변수 선언이 함수의 맨 위로 이동하고 for 루프가 for-each로 변경되었습니다. 모두 미묘한 버그가 발생할 수 있습니다. 이러한 변경 사항을 안전하게 적용하려면 현혹적인 기술이 필요합니다.
Johntron

4

그러나 주요 서식 변경에서 코드 변경을 어떻게 추적합니까?

서식 변경 코드 변경입니다. 다른 코드 변경과 같이 처리하십시오. 중요한 프로젝트를 수행 한 사람은 누군가가 일부 코드를 "단순히"다시 정하기로 결정했을 때 생성 된 버그 및 기타 문제를 보았을 것입니다.

그러나 그것은 많은 일이며, 다른 모든 사람들은 일이 진행되는 동안 일을 멈추거나 모든 합병의 어머니를 위해 준비해야합니다.

왜 모든 것을 동시에 다시 포맷해야합니까? 특히 재 포맷을해도 코드의 의미가 바뀌지 않으면 파일을 개별적으로 다시 포맷하고 진행하면서 파일을 체크인 할 수 있어야합니다. 더 나은 방법은 팀의 모든 사람들이 스타일에 동의하도록하고 (그렇지 않으면 다시 포맷 할 필요가 없음) 다른 작업을하는 동안 모두 다시 포맷하도록 관리하는 것입니다. 잠시 후, 나머지 프로젝트를 방해하지 않으면 서 대부분의 코드를 다룰 것입니다.


1

내가 본 두 가지 방법이 있습니다.

1. commit-hook에서 코드 포맷

코드를 제출 한 후 코드를 변경하는 것이 처음에는 모발이기는하지만, 형식 재 지정 절차 (예 : astyle )가 코드를 손상시키지 않으면 안전한 작동입니다. 시간이 지남에 따라 전체 팀은 모든 코드가 결국 동일하게 보입니다. 포괄적 인 단위 / 자동 테스트를 수행하면 아무런 문제가 발생하지 않습니다.

2. 모든 코드의 일회성 재 포맷

이것은 내 경험에서 더 위험하며 빅뱅에서의 문제 추적을 어렵게하지만 가능합니다. 이후에 모든 테스트를 실행해야합니다. 코딩 스타일의 경우, 대부분의 차이는 공백 또는 들여 쓰기 또는 줄 바꿈 사용과 관련이 있습니다. 적절한 병합 도구는 모든 공백 차이를 무시하도록 지시 할 수 있으므로 병합에 도움이됩니다.


1
대부분의 코드베이스에서 리플을 켰을 때 하나의 옵션을 사용하지 않으면 각 파일을 변경하는 것과 동일한 큰 결과를 초래할까요?
서명

@Sign : 정확히 내 요점-커밋 훅이 바뀌면 역사는 거의 쓸모없는 것으로 악화 될 수 있습니다. 기능을 변경하지 않는 서식은 커밋해서는 안되며 코드 기록 전체에 이식되어야합니다.
l0b0

1
IDE가 지원하는 경우 3) 저장할 때 IDE 자동 형식이 있습니다. 그런 다음 어디에서나 동일한 설정을 사용하십시오. IDE에서 기본값을 사용하는 경우 가장 쉽습니다.

이 두 가지 접근 방식을 모두 수행했습니다. 첫 번째 방법은 새 파일이 처음 커밋 될 때마다 많은 변화가 있기 때문에 매우 방해가됩니다. 두 번째 방법은 반창고를 제거하는 것과 같이 팀에 더 좋습니다.
Druska
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.