해결되지 않은 변경 사항을 커밋하지 않는 이유는 무엇입니까?


15

전통적인 VCS에서는 빌드를 중단 할 수 있기 때문에 해결되지 않은 파일을 커밋하지 않는 이유를 이해할 수 있습니다. 그러나 DVCS에서 해결되지 않은 파일을 커밋해서는 안되는 이유를 이해하지 못합니다 (일부 파일은 실제로 파일 커밋을 방해 합니다).

대신에, 나는 당신의 저장소에서 고정되어야한다고 생각 밀어당기 하지만, 커밋하지.

병합 과정에서 커밋 할 수 있다는 것은 몇 가지 장점이 있습니다 (내가 본 것처럼).

  • 실제 병합 변경 사항은 기록에 있습니다.
  • 병합이 매우 큰 경우 정기적으로 커밋 할 수 있습니다.
  • 실수 한 경우 전체 병합을 다시 실행할 필요없이 롤백하는 것이 훨씬 쉽습니다.
  • 파일이 확인 된 것으로 표시 될 때까지 파일이 확인되지 않은 것으로 플래그 된 상태로 남아있을 수 있습니다. 이것은 밀거나 당기는 것을 방지합니다.

잠재적으로 일련 의 변경 세트 가 단일 변경 세트 대신 병합으로 작동하도록 할 수도 있습니다 . 이렇게하면 여전히 같은 도구를 사용할 수 있습니다 git rerere.

그렇다면 해결되지 않은 파일을 사용하여 커밋하는 이유는 무엇입니까? 전통 이외의 다른 이유가 있습니까?


1
누구에 의해 눈살을 찌푸 리거나 예방합니까?
pdr

@ pdr 내가 일한 일부 개발자는 눈살을 찌푸렸다. 적어도 hg 1.6병합 후에는 파일이 해결되지 않은 것으로 표시됩니다. hg수 없습니다 해결 당신이 그들을 표시 할 때까지 커밋하자 (반드시 당신이 실제로이를 해결하는 것은 아닙니다,하지만 난 생각이 그 가정 것이다).
폭발 약

1
"해결되지 않은 파일"이라는 말은 실제로 "해결되지 않은 병합"을 의미합니까?
pdr

@pdr no는 hg실제로 "해결됨"으로 플래그가 지정되었거나 표시되지 않은 파일 목록을 유지 관리합니다 (사용 hg resolve). 어떤이있는 경우 U이 목록에있는 파일, 당신이 커밋하지 않습니다.
폭발 약

1
hg resolve충돌과의 병합에 특별히 사용됩니다. selenic.com/mercurial/hg.1.html#resolve를 참조하십시오 . Note that Mercurial will not let you commit files with unresolved merge conflicts. You must use hg resolve -m ... before you can commit after a conflicting merge.
Mike Partridge

답변:


6

내가 볼 수있는 가장 큰 문제는 물건이 반 병합되어 (아마도) 제대로 작동하지 않는 커밋 창을 만드는 것입니다. 최종 로컬 커밋 세트를 푸시하면 모든 중간 커밋이 다른 모든 사람에게도 적용됩니다. 이상적으로, 나는 당길 수 있어야 어떤 커밋하고 코드가 작동합니다. 병합 도중 커밋을 시작하면 코드 상태가 제대로 정의되지 않습니다.

당신이 할 수있는 한 가지는 병합에 로컬 커밋을 한 다음 푸시 할 때 하나의 큰 커밋으로 묶는 것입니다 (그러나 어떤 vc가 이것을 지원하는지 확실하지는 않지만). 이것이 당신이 언급 한 이점 중 일부를 얻을 수는 있지만, 추가 복잡성의 가치가 있는지 확실하지 않습니다 (우리는 이미 상당히 혼란스럽고 복잡한 영역을 다루고 있습니다).


5
나는 커밋을 풀고 작동시키는 능력에 동의한다는 것을 모른다. DVCS에서 커밋하는 많은 요점은 당신의 진보 를 커밋하는 것이므로, 물건은 많은 시간이 지났거나 불완전하다. .
폭발 약

2
항상 커밋을 수행하면 좋은 이점이 있습니다. 예를 들어, 버그가 도입 된 시점을 추적하려는 경우 내역을 탐색하여 문제가 발생한 시점을 확인할 수 있습니다 (vcs는 내역에 대한 이진 검색을 수행하는 명령도 있음). 커밋이 없으면 버그를 효과적으로 추적 할 수 없습니다.
Oleksi

1
Git은 번들 커밋을 지원합니다.
deltree

3

나는 Git에 대해 가장 잘 알고 있으므로 그 관점에 대해 대답 할 것이다.

난 당신이 이유 표시되지 않습니다 또는 좋은의 VCS는 코드이었다 특히 경우, 병합 파일을 커밋 허용 할 것입니다. 저장소를 일관된 상태로 유지해야하며 제안한 내용이 커밋 원 자성을 위반합니다. 많은 VCS는 물리적으로 파일을 변경하여 충돌이있는 위치를 표시합니다. Git, SVN 및 CVS는 >>>> <<<< 유형 마커를 사용합니다. 원자 저장소 수준 커밋 및 병합을 사용하는 VCS에서는 다른 사람에게는 의미가없는 노드를 만들었을 것입니다. 소프트웨어 개발에서 프로젝트를 빌드 할 수 없습니다. 그룹 문서에서 어느 변경이 올바른지 아무도 모릅니다.

이제 Git은이를 허용 할 수있는 커밋 유형 인이 도구를 제공합니다. 예를 들어 푸시하기 전에 병합 커밋을 모두 스쿼시 할 수 있습니다. 이는 일반적인 병합 커밋과 동일합니다.

혜택 목록에 대한 특정 관심사 :

  1. 실제 병합 변경 사항은 기록에 있습니다. 왜 추가 정보가 필요합니까? DVCS는 제한된 지역으로 갈등을 제한하는 데 매우 좋습니다. 유지할 변경 세트를 선택한 후에는 병합 커밋 노드의 사본을 이전 사본과 비교하면 정확히이 결과를 얻을 수 있습니다.
  2. 병합이 매우 큰 경우 정기적으로 커밋 할 수 있습니다. 이것은 유효한 관심사이지만 처음에는 여기에 와서는 안됩니다. 지점은 지속적으로 업스트림 변경을 추진해야하므로 이런 일이 발생하지 않습니다. rebase한 번에 한 번의 커밋 과 같은 도구를 선택 하거나 체리 픽킹하는 것도 일부 상황에서 도움이 될 수 있습니다.
  3. 실수를 한 경우 전체 병합을 다시 실행할 필요없이 롤백하는 것이 훨씬 쉽습니다. 위를 참조하십시오-당신의 갈등이 다루기 어려워서는 안됩니다.

이 제안이 작동 할 수있는 유일한 방법은 분기가 전체 병합이 원자 적 인 경우입니다-일련의 커밋을 볼 수 있지만 커밋 트리에서 하나의 노드로 처리 해야하는 더 큰 병합 커밋의 단계 일뿐입니다. . 현재 VCS가 이러한 유형의 워크 플로를 지원하지 않는다고 생각하며 그것이 필요하다고 생각하지 않습니다.


갈등은 아마도 관리 할 수없는 것이 아니어야 하지만 종종 (적어도 나의 경험으로는) 있습니다. 나는 전체 합병 원자 적 이어야 한다고 생각한다 . 그것이 제가 제안하는 것입니다. 필요하지 않을 수도 있습니다. 왜 그것이 이루어지지 않았는지 궁금합니다. 또한 충돌시 반드시 하나 또는 다른 옵션을 선택할 수는 없습니다. 때로는 두 가지 변경의 조합입니다. 이것은 특히 혼란 스럽다.
폭발 약

"저장소를 일관된 상태로 유지해야합니다." 나는 그것이 사실이라고 생각하지 않습니다. 로컬 저장소는 신사가 아닌 작업 공간입니다. 병합 도중 커밋하는 것이 도움이되면 IMHO를 수행하십시오. 더 잘 모르기 때문에이 작업을 수행하면 수행하지 않는 것이 좋습니다. 그러나 숙련 된 프로그래머라면 자신에게 가장 잘 맞는 것을해야합니다. 로컬 저장소를 깨끗하게 유지하는 것에 대해 독단적 인 태도를 취하지 마십시오.
Bryan Oakley

1

내 주된 경험은 Mercurial에 있지만 git을 산발적으로 사용합니다.

Mercurial은 해결되지 않은 파일을 커밋하는 것을 허용하지 않으며 사용자를 실망 시킵니다. 필요없는 변경 사항을 가져 오기 전에 밀어 넣는 것과 같습니다.

Mercurial에서해야 할 일은 파일을 커밋하려는 방식으로 파일을 확보 한 것입니다.

hg resolve --mark --all
hg commit -m "I'm such a rebel"

--mark will ... 병합 도구를 요구하지 않고 파일을 해결 된 것으로 표시합니다. --all은 충돌이있는 모든 파일 표시를 선택합니다.

당기지 않고 밀고 싶을 때 (그리고 결과적으로 다른 변경 사항을 병합 해야하는 경우) Jedi처럼하십시오 .

hg push --force

다음 사람은 +1 머리를 얻습니다 (말장난 의도 없음)

Git과 동일한 작업을 수행 할 수있는 방법이 있다고 확신합니다 (아마도 더 복잡 할 수도 있음).


1

git을 병합하면 즉시 모든 변경 사항 (병합 충돌 포함)을 커밋합니다. 그런 다음 다음 커밋에서 텍스트 편집기를 통해 병합 충돌을 해결합니다. 충돌이 해결 된 후 원하는 경우 푸시합니다.

솔직히 나는 왜 다른 사람들이 이런 식으로하지 않는지 이해하지 못하거나 자식이 그것을 강제하지 않습니다.

  • "병합 커밋"은 이제 정확히 병합해야 할 사항에 대한 명확한 기록입니다.
  • 다음 커밋은 병합 충돌을 해결하기 위해 수행 한 작업을 정확하게 보여줍니다.
  • 푸시하면 충돌이 해결되고 지점 끝에서 빌드가 중단되지 않습니다.
  • 언제든지 충돌 해결을 망칠 경우 간단히 "포스트 병합"커밋 중 하나로 되돌리고 다시 시도 할 수 있습니다.

커밋 하기 전에 충돌을 해결하는 표준 워크 플로의 큰 단점은 로컬 복사본의 변경 사항이 몰래 들어올 수 있다는 것입니다. 추가 된 내용은 대규모 병합 차이로 인한 코드 검토에서 숨겨져 실수로 API를 커밋했음을 알지 못합니다. 키 등

위에서 설명한 내 워크 플로는이 로컬 복사본 문제를 방지하고 코드 검토자가 표준 커밋 차이와 정확히 같은 커밋 차이에서 병합 해결에 대한 세부 정보 만 검사 할 수 있도록합니다.


0

나는 작은 변화를 추진하는 것이 최선이라고 생각하고 (물론 항상 없음) 가능하면 자주 밀어 하지 않는 반 전체 (우리 모두 메이크업 실수를하지 않는 빌드, 또는 인 코드를 커밋,하지만 돈 의도적으로하지 마십시오). 나는 또한 자식에서 왔으며, 내가 생각하는 가장 좋은 것 중 하나는 데스크탑에 실행 가능한 저장소의 사본을 가질 수 있다는 사실입니다. 그런 다음 마음의 내용으로 수정할 수 있습니다. 큰 변화가 끝나면 보내십시오.

git으로 많은 오픈 소스를 수행하는 것이 저에게 가장 큰 좌절은 반으로 코드가 리포에 들어가고 빌드를 시도하는 것이었지만, 그 사람은 절반의 작업을 수행하여 "지금 바빠서" , 일주일 안에 끝낼 것입니다. " 그래서 나는 그것을 긁어 모으거나 (남자를 귀찮게 할) 시간을내어 완성하고 완전히 통합해야합니다.

내 관점에서, 반 엉덩이 물건을 로컬로 유지하고, 좋은 물건을 전선으로 보냅니다.


0

도구의 노예가되지 마십시오.

VCS의 목표는 작업을 수행 할 수 있도록하는 것입니다. 당신의 임무는 원시 로컬 저장소를 유지하는 것이 아니라 코드를 작성하는 것입니다. 초기에 커밋하고 종종 로컬에서 더 잘 일할 수 있다면 그렇게하십시오.

그러나 깨진 코드를 업스트림으로 푸시 해서는 안됩니다 .


0

근본적으로 나쁜 생각이기 때문에 팔러 상태에있는 저장소로 이어질 것입니다 (그리고 항상 최소한 하나의 사본을 가져야한다고 주장 할지라도, 어디에서나 밀릴 것이라고 가정하는 발진).

대규모 / 복잡한 병합의 경우 진행중인 작업을 저장하고 참조 점을 설정하려고하지만 여전히 해결해야 할 엉망인 상태로 시스템을 남겨두고 있음을 알 수 있습니다.

또한 헤드보다 이전에 병합 할 수있는 대안이 있습니다.이 옵션을 사용하면 서사적 병합없이 (또는 적어도 이해하기 쉬운 더 큰 병합으로) 변경 사항에 적응할 수 있습니다.

이것은 git의 rebase가 특히 유용하다는 것을 알았습니다 (리베이스에 관한 일반적인주의 사항에 따라 다름). 작은 조각으로 갈등을 해결하기 위해 현재 상태 위에서 변경 사항을 재생하기 때문입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.